Done with categories and labels in both app and org apps

This commit is contained in:
monilprajapati
2024-11-15 13:08:27 +05:30
parent 2bf969bd14
commit 8e9b1cf1ea
+104 -94
View File
@@ -11,6 +11,7 @@ import {
Tooltip, Tooltip,
Box, Box,
CircularProgress, CircularProgress,
Checkbox,
} from "@mui/material"; } from "@mui/material";
import { Context } from "../context/ContextApi.jsx"; import { Context } from "../context/ContextApi.jsx";
import Add from '@mui/icons-material/Add'; import Add from '@mui/icons-material/Add';
@@ -18,7 +19,7 @@ import InputAdornment from '@mui/material/InputAdornment';
import Search from '@mui/icons-material/Search'; import Search from '@mui/icons-material/Search';
import ClearIcon from '@mui/icons-material/Clear'; import ClearIcon from '@mui/icons-material/Clear';
import { ClearRefinements, connectHits, connectSearchBox, connectStateResults, InstantSearch, RefinementList } from "react-instantsearch-dom"; import { ClearRefinements, connectHits, connectSearchBox, connectStateResults, InstantSearch, RefinementList, connectRefinementList } from "react-instantsearch-dom";
import { removeQuery } from "../components/ScrollToTop.jsx"; import { removeQuery } from "../components/ScrollToTop.jsx";
import { toast } from "react-toastify"; import { toast } from "react-toastify";
import algoliasearch from "algoliasearch/lite"; import algoliasearch from "algoliasearch/lite";
@@ -173,7 +174,6 @@ const AppCard = ({ data, index, mouseHoverIndex, setMouseHoverIndex, globalUrl,
const Hits = ({ const Hits = ({
userdata, userdata,
hits, hits,
algoliaSelectedCategories,
setIsAnyAppActivated, setIsAnyAppActivated,
searchQuery, searchQuery,
globalUrl, globalUrl,
@@ -200,10 +200,6 @@ const Hits = ({
}, [searchQuery, hits]) }, [searchQuery, hits])
const filteredHits = hits?.filter(hit => {
if (algoliaSelectedCategories?.length === 0) return true; // If no categories are selected, show all hits
return hit.categories?.some(category => algoliaSelectedCategories.includes(category));
});
// const fetchUserData = useCallback(async () => { // const fetchUserData = useCallback(async () => {
// try { // try {
@@ -298,7 +294,7 @@ const Hits = ({
<div> <div>
{!isLoading ? ( {!isLoading ? (
<div> <div>
{filteredHits?.length === 0 && searchQuery.length >= 0 && showNoAppFound ? ( {hits?.length === 0 && searchQuery.length >= 0 && showNoAppFound ? (
<Typography variant="body1" style={{ marginTop: '30%' }}>No Apps Found</Typography> <Typography variant="body1" style={{ marginTop: '30%' }}>No Apps Found</Typography>
) : ( ) : (
<Grid item spacing={2} justifyContent="flex-start"> <Grid item spacing={2} justifyContent="flex-start">
@@ -322,7 +318,7 @@ const Hits = ({
scrollbarColor: "#494949 #2f2f2f", scrollbarColor: "#494949 #2f2f2f",
}} }}
> >
{filteredHits?.map((data, index) => { {hits?.map((data, index) => {
const appUrl = const appUrl =
isCloud isCloud
? `/apps/${data.objectID}?queryID=${data.__queryID}` ? `/apps/${data.objectID}?queryID=${data.__queryID}`
@@ -539,6 +535,47 @@ const Hits = ({
); );
} }
// Custom Category Dropdown Component
const CategoryDropdown = ({ items, currentRefinement, refine }) => {
const handleChange = (event) => {
const value = event.target.value;
refine(value);
};
return (
<Select
fullWidth
variant="outlined"
value={currentRefinement}
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',
}}
renderValue={(selected) => selected.length ? selected.join(', ') : 'All Categories'}
>
<MenuItem disabled value="">
All Categories
</MenuItem>
{items.map(item => (
<MenuItem key={item.label} value={item.label}>
<Checkbox checked={currentRefinement.includes(item.label)} />
{item.label} ({item.count})
</MenuItem>
))}
</Select>
);
};
const CustomCategoryDropdown = connectRefinementList(CategoryDropdown);
// Main Apps Component // Main Apps Component
const Apps2 = (props) => { const Apps2 = (props) => {
const { globalUrl, isLoaded, serverside, userdata, isLoggedIn } = props; const { globalUrl, isLoaded, serverside, userdata, isLoggedIn } = props;
@@ -546,9 +583,8 @@ const Apps2 = (props) => {
const { leftSideBarOpenByClick } = useContext(Context); const { leftSideBarOpenByClick } = useContext(Context);
const location = useLocation(); const location = useLocation();
const [searchQuery, setSearchQuery] = useState(""); const [searchQuery, setSearchQuery] = useState("");
const [selectedCategory, setSelectedCategory] = useState(""); const [selectedCategory, setSelectedCategory] = useState([]);
const [algoliaSelectedCategories, setAlgoliaSelectedCategories] = useState([]); const [selectedLabel, setSelectedLabel] = useState([]);
const [selectedLabel, setSelectedLabel] = useState("");
const [algoliaSelectedLabels, setAlgoliaSelectedLabels] = useState([]); const [algoliaSelectedLabels, setAlgoliaSelectedLabels] = useState([]);
const [currTab, setCurrTab] = useState(0); const [currTab, setCurrTab] = useState(0);
const [categories, setCategories] = useState([]); const [categories, setCategories] = useState([]);
@@ -679,7 +715,7 @@ const Apps2 = (props) => {
const findTopTags = () => { const findTopTags = () => {
const tagCountMap = {}; const tagCountMap = {};
const apps = currTab === 1 ? userApps : orgApps; const apps = currTab === 1 ? userApps : orgApps;
if (Array.isArray(apps)) { if (Array.isArray(apps)) {
apps.forEach((app) => { apps.forEach((app) => {
const tags = app.tags; const tags = app.tags;
@@ -725,22 +761,22 @@ const Apps2 = (props) => {
); );
const matchesSelectedCategories = ( const matchesSelectedCategories = (
selectedCategory === "" || // If no category is selected, match all apps selectedCategory.length === 0 || // If no category is selected, match all apps
(app.categories && app.categories.some(category => (app.categories && app.categories.some(category =>
selectedCategory.includes(category) selectedCategory.includes(category)
)) ))
); );
const matchesSelectedTags = ( const matchesSelectedTags = (
selectedLabel === "" || // If no label is selected, match all apps selectedLabel.length === 0 || // If no label is selected, match all apps
(app.tags && app.tags.some(tag => (app.tags && app.tags.some(tag =>
tag.toLowerCase().includes(selectedLabel.toLowerCase()) selectedLabel.includes(tag)
)) ))
); );
return matchesSearchQuery && matchesSelectedCategories && matchesSelectedTags; return matchesSearchQuery && matchesSelectedCategories && matchesSelectedTags;
}) : []; }) : [];
setAppsToShow(filteredUserAppdata); setAppsToShow(filteredUserAppdata);
}, [searchQuery, selectedCategory, selectedLabel]); }, [searchQuery, selectedCategory, selectedLabel]);
@@ -779,13 +815,6 @@ const Apps2 = (props) => {
// padding: '20px 380px', // padding: '20px 380px',
}; };
const CustomClearRefinements = connectStateResults(({ searchResults, ...rest }) => {
const hasFilters = searchResults && searchResults.nbHits !== searchResults.nbSortedHits;
return <ClearRefinements translations={{ reset: <span style={{ textDecoration: 'underline' }}>Clear All</span> }} {...rest} disabled={!hasFilters} />;
});
const SearchBox = ({ refine, searchQuery, setSearchQuery }) => { const SearchBox = ({ refine, searchQuery, setSearchQuery }) => {
const inputRef = React.useRef(null); // Create a ref for the input field const inputRef = React.useRef(null); // Create a ref for the input field
@@ -868,21 +897,15 @@ const Apps2 = (props) => {
const CustomHits = connectHits(Hits) const CustomHits = connectHits(Hits)
const handleCategoryChange = (selectedValue) => { const handleCategoryChange = (event) => {
setAlgoliaSelectedCategories(prev => { const value = event.target.value;
if (prev.includes(selectedValue)) { setSelectedCategory(value);
// If the category is already selected, remove it
return prev.filter(category => category !== selectedValue);
} else {
// Otherwise, add it to the selected categories
return [...prev, selectedValue];
}
});
}; };
useEffect(() => { const handleLabelChange = (event) => {
console.log("algoliaSelectedCategories", algoliaSelectedCategories) const value = event.target.value;
}, [algoliaSelectedCategories]) setSelectedLabel(value);
};
return ( return (
@@ -942,75 +965,63 @@ const Apps2 = (props) => {
} }
</div> </div>
<div style={{ flex: 1, marginRight: 10 }}> <div style={{ flex: 1, marginRight: 10 }}>
<Select {currTab === 2 ? (
fullWidth <CustomCategoryDropdown attribute="categories" />
variant="outlined" ) : (
value={selectedCategory} <Select
onChange={(e) => setSelectedCategory(e.target.value)} fullWidth
displayEmpty variant="outlined"
style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" }} value={selectedCategory}
> onChange={handleCategoryChange}
<MenuItem value=""> displayEmpty
All Categories multiple
</MenuItem> style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)", maxWidth: "300px" }}
{ renderValue={(selected) => selected.length ? selected.join(', ') : 'All Categories'}
currTab === 0 && >
( <MenuItem disabled value="">
categories?.map((category) => ( All Categories
<MenuItem key={category.category} value={category.category}> </MenuItem>
{category.category} {categories?.map((category) => (
<MenuItem key={category.category} value={category.category}>
<Checkbox checked={selectedCategory.includes(category.category)} />
{category.category}
</MenuItem>
))}
{
selectedCategory.length > 0 && (
<MenuItem onClick={() => setSelectedCategory([])} style={{ display: 'flex', justifyContent: 'center', padding: '10px', backgroundColor: '#212121', color: '#fff', marginTop: '10px', cursor: 'pointer' }}>
<Typography style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>Remove All Categories</Typography>
</MenuItem> </MenuItem>
)) )
) }
} </Select>
{ )}
currTab === 2 &&
(
<div style={{ padding: "5px 10px" }}>
<RefinementList
attribute="categories"
defaultRefinement={algoliaSelectedCategories}
onChange={(selectedItems) => {
handleCategoryChange(selectedItems);
}}
transformItems={(items) => {
console.log("items", items)
return items;
}}
/>
</div>
)
}
</Select>
</div> </div>
<div style={{ flex: 1, marginRight: 10 }}> <div style={{ flex: 1, marginRight: 10 }}>
<Select <Select
fullWidth fullWidth
variant="outlined" variant="outlined"
value={selectedLabel} value={selectedLabel}
onChange={(e) => setSelectedLabel(e.target.value)} onChange={handleLabelChange}
displayEmpty displayEmpty
style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)" }} multiple
style={{ width: '100%', borderRadius: '7px', fontFamily: "var(--zds-typography-base,Inter,Helvetica,arial,sans-serif)", maxWidth: "300px" }}
renderValue={(selected) => selected.length ? selected.join(', ') : 'All Labels'}
> >
<MenuItem value=""> <MenuItem disabled value="">
All Labels All Labels
</MenuItem> </MenuItem>
{labels?.map((tag) => (
<MenuItem key={tag.tag} value={tag.tag}>
<Checkbox checked={selectedLabel.includes(tag.tag)} />
{tag.tag}
</MenuItem>
))}
{ {
currTab === 0 && selectedLabel.length > 0 && (
( <MenuItem onClick={() => setSelectedCategory([])} style={{ display: 'flex', justifyContent: 'center', padding: '10px', backgroundColor: '#212121', color: '#fff', marginTop: '10px', cursor: 'pointer' }}>
labels?.map((tag) => ( <Typography style={{ textAlign: 'center', width: '100%', fontWeight: 'bold' }}>Remove All Labels</Typography>
<MenuItem value={tag.tag}> </MenuItem>
{tag.tag}
</MenuItem>
))
)
}
{
currTab === 2 &&
(
<div style={{ padding: "5px 10px" }}>
<RefinementList attribute="action_labels" />
</div>
) )
} }
</Select> </Select>
@@ -1117,7 +1128,6 @@ const Apps2 = (props) => {
hitsPerPage={5} hitsPerPage={5}
globalUrl={globalUrl} globalUrl={globalUrl}
searchQuery={searchQuery} searchQuery={searchQuery}
algoliaSelectedCategories={algoliaSelectedCategories}
mouseHoverIndex={mouseHoverIndex} mouseHoverIndex={mouseHoverIndex}
setMouseHoverIndex={setMouseHoverIndex} setMouseHoverIndex={setMouseHoverIndex}
/> />