Merge remote-tracking branch 'origin/decal-list' into main-demo

This commit is contained in:
2025-08-29 12:52:50 +05:30
2 changed files with 156 additions and 70 deletions

View File

@@ -54,39 +54,54 @@ const Assets: React.FC = () => {
const [searchValue, setSearchValue] = useState<string>(""); const [searchValue, setSearchValue] = useState<string>("");
const [selectedCategory, setSelectedCategory] = useState<string | null>(null); const [selectedCategory, setSelectedCategory] = useState<string | null>(null);
const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]); const [categoryAssets, setCategoryAssets] = useState<AssetProp[]>([]);
const [decalAsset, setDecalAsset] = useState<any>();
const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[]>([]); const [filtereredAssets, setFiltereredAssets] = useState<AssetProp[] | []>(
[]
);
const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]); const [categoryList, setCategoryList] = useState<CategoryListProp[]>([]);
const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets const [isLoading, setisLoading] = useState<boolean>(false); // Loading state for assets
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
const handleSearchChange = (value: string) => { const handleSearchChange = (value: string) => {
const searchTerm = value.toLowerCase(); const searchTerm = searchValue
? searchValue.toLowerCase()
: value.toLowerCase();
setSearchValue(value); setSearchValue(value);
if (searchTerm.trim() === "" && !selectedCategory) { if (searchTerm.trim() === "" && !selectedCategory) {
setCategoryAssets([]); setCategoryAssets([]);
return; return;
} }
const filteredModels = filtereredAssets?.filter((model) => { if (selectedCategory === "Decals" || selectedSubCategory) {
if (!model?.tags || !model?.filename || !model?.category) return false; const filteredModels = decalAsset?.filter((model: any) =>
if (searchTerm.startsWith(":") && searchTerm.length > 1) { model.decalName?.toLowerCase().includes(searchTerm.toLowerCase())
const tagSearchTerm = searchTerm.slice(1); );
return model.tags.toLowerCase().includes(tagSearchTerm); setCategoryAssets(filteredModels);
} else if (selectedCategory) { } else {
return ( const filteredModels = filtereredAssets?.filter((model) => {
model.category if (!model?.tags || !model?.filename || !model?.category) return false;
.toLowerCase() if (searchTerm.startsWith(":") && searchTerm.length > 1) {
.includes(selectedCategory.toLowerCase()) && const tagSearchTerm = searchTerm.slice(1);
model.filename.toLowerCase().includes(searchTerm) return model.tags.toLowerCase().includes(tagSearchTerm);
); } else if (selectedCategory) {
} else { return (
return model.filename.toLowerCase().includes(searchTerm); model.category
} .toLowerCase()
}); .includes(selectedCategory.toLowerCase()) &&
model.filename.toLowerCase().includes(searchTerm)
);
} else {
return model.filename.toLowerCase().includes(searchTerm);
}
});
setCategoryAssets(filteredModels); setCategoryAssets(filteredModels);
}
}; };
useEffect(() => { useEffect(() => {
if (selectedCategory === "Decals") return;
const filteredAssets = async () => { const filteredAssets = async () => {
try { try {
const filt = await fetchAssets(); const filt = await fetchAssets();
@@ -96,7 +111,18 @@ const Assets: React.FC = () => {
} }
}; };
filteredAssets(); filteredAssets();
}, [categoryAssets]); }, [categoryAssets, selectedCategory]);
useEffect(() => {
if (
(searchValue.trim() === "" && selectedCategory === "Decals") ||
selectedSubCategory
) {
const filteredModels = decalAsset?.filter((model: any) =>
model.decalName?.toLowerCase().includes(searchValue.toLowerCase())
);
setCategoryAssets(filteredModels);
}
}, [selectedSubCategory, decalAsset, searchValue]);
useEffect(() => { useEffect(() => {
setCategoryList([ setCategoryList([
@@ -136,8 +162,10 @@ const Assets: React.FC = () => {
// setSelectedCategory(asset); // setSelectedCategory(asset);
try { try {
const res = await getCategoryDecals(asset); const res = await getCategoryDecals(asset);
setCategoryAssets(res); setCategoryAssets(res);
setFiltereredAssets(res); setFiltereredAssets(res);
setDecalAsset(res);
setisLoading(false); // End loading setisLoading(false); // End loading
// eslint-disable-next-line // eslint-disable-next-line
} catch (error) { } catch (error) {
@@ -153,11 +181,9 @@ const Assets: React.FC = () => {
{ name: "Informational", icon: <DecalInfoIcon /> }, { name: "Informational", icon: <DecalInfoIcon /> },
]; ];
const { selectedSubCategory, setSelectedSubCategory } = useDecalStore();
return ( return (
<div className="assets-container-main"> <div className="assets-container-main">
<Search onChange={handleSearchChange} /> <Search onChange={handleSearchChange} value={searchValue} />
<div className="assets-list-section"> <div className="assets-list-section">
<section> <section>
{(() => { {(() => {
@@ -175,40 +201,100 @@ const Assets: React.FC = () => {
</p> </p>
</div> </div>
<div className="assets-container"> <div className="assets-container">
{categoryAssets?.map((asset: any, index: number) => ( {selectedCategory == "Decals" ? (
<div <>
key={`${index}-${asset.filename}`} <div className="catogory-asset-filter">
className="assets" {activeSubcategories.map((cat, index) => (
id={asset.filename} <div
title={asset.filename} key={index}
> className={`catogory-asset-filter-wrapper ${
<img selectedSubCategory === cat.name
src={asset?.thumbnail} ? "active"
alt={asset.filename} : ""
className="asset-image" }`}
onPointerDown={() => { onClick={() => {
setSelectedItem({ fetchCategoryDecals(cat.name);
name: asset.filename, setSelectedSubCategory(cat.name);
id: asset.AssetID, }}
type: >
asset.type === "undefined" <div className="sub-catagory">{cat.icon}</div>
? undefined <div className="sub-catagory">{cat.name}</div>
: asset.type, </div>
}); ))}
}}
/>
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div> </div>
</div> {categoryAssets?.map((asset: any, index: number) => (
))} <div
key={`${index}-${asset}`}
className="assets"
id={asset.decalName}
title={asset.decalName}
>
<img
src={asset?.decalImage}
alt={asset.decalName}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.decalName,
id: asset.id,
type:
asset.type === "undefined"
? undefined
: asset.type,
category: asset.category,
// subType: asset.subType,
});
}}
/>
<div className="asset-name">
{asset.decalName
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() +
word.slice(1)
)
.join(" ")}
</div>
</div>
))}
</>
) : (
categoryAssets?.map((asset: any, index: number) => (
<div
key={`${index}-${asset.filename}`}
className="assets"
id={asset.filename}
title={asset.filename}
>
<img
src={asset?.thumbnail}
alt={asset.filename}
className="asset-image"
onPointerDown={() => {
setSelectedItem({
name: asset.filename,
id: asset.AssetID,
type:
asset.type === "undefined"
? undefined
: asset.type,
});
}}
/>
<div className="asset-name">
{asset.filename
.split("_")
.map(
(word: any) =>
word.charAt(0).toUpperCase() + word.slice(1)
)
.join(" ")}
</div>
</div>
))
)}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -5,20 +5,20 @@ import { useSceneContext } from "../../../scene/sceneContext";
import { useViewSceneStore } from "../../../../store/builder/store"; import { useViewSceneStore } from "../../../../store/builder/store";
function VehicleInstances() { function VehicleInstances() {
const { vehicleStore } = useSceneContext(); const { vehicleStore } = useSceneContext();
const { vehicles } = vehicleStore(); const { vehicles } = vehicleStore();
const { viewSceneLabels } = useViewSceneStore(); const { viewSceneLabels } = useViewSceneStore();
return ( return (
<> <>
{vehicles.map((vehicle: VehicleStatus) => ( {vehicles.map((vehicle: VehicleStatus) => (
<React.Fragment key={vehicle.modelUuid}> <React.Fragment key={vehicle.modelUuid}>
<VehicleInstance agvDetail={vehicle} /> <VehicleInstance agvDetail={vehicle} />
{viewSceneLabels && <VehicleContentUi vehicle={vehicle} />} {viewSceneLabels && <VehicleContentUi vehicle={vehicle} />}
</React.Fragment> </React.Fragment>
))} ))}
</> </>
); );
} }
export default VehicleInstances; export default VehicleInstances;