Skip to content

[hackaton] solar assets layer #8161

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 59 commits into
base: master
Choose a base branch
from
Open

[hackaton] solar assets layer #8161

wants to merge 59 commits into from

Conversation

seljaks
Copy link
Contributor

@seljaks seljaks commented May 22, 2025

No description provided.

});
if (solarAssetFeature) {
console.log('[Map.tsx onMouseMove] Solar asset detected:', solarAssetFeature);
const properties = (solarAssetFeature.properties as Record<string, any>) || {};

Check warning

Code scanning / ESLint

Disallow the `any` type Warning

Unexpected any. Specify a different type.

Copilot Autofix

AI 5 days ago

To fix the issue, we need to replace the any type with a more specific type for the properties object. Since the structure of properties is not provided, we can define a custom type or interface that represents its expected shape. If the structure is dynamic but has some known keys, we can use an index signature or a union of known keys. If the structure is entirely unknown, we can use Record<string, unknown> as a safer alternative to any.

The changes will involve:

  1. Defining a new type or interface for the properties object.
  2. Updating the type assertion on line 645 to use the new type instead of any.
Suggested changeset 1
web/src/features/map/Map.tsx

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/web/src/features/map/Map.tsx b/web/src/features/map/Map.tsx
--- a/web/src/features/map/Map.tsx
+++ b/web/src/features/map/Map.tsx
@@ -644,3 +644,3 @@
       if (solarAssetFeature) {
-        const properties = (solarAssetFeature.properties as Record<string, any>) || {};
+        const properties = (solarAssetFeature.properties as Record<string, unknown>) || {};
         const assetInfo = {
EOF
@@ -644,3 +644,3 @@
if (solarAssetFeature) {
const properties = (solarAssetFeature.properties as Record<string, any>) || {};
const properties = (solarAssetFeature.properties as Record<string, unknown>) || {};
const assetInfo = {
Copilot is powered by AI and may make mistakes. Always verify output.
Copy link
Member

@VIKTORVAV99 VIKTORVAV99 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Long review and a lot of comments, sorry about that but it's a big PR...

Comment on lines +186 to +196
{selectedSolarAsset ? (
<div className="pointer-events-none absolute inset-0 z-10 sm:flex sm:w-[calc(14vw_+_16rem)]">
<Suspense>
<SolarAssetPanel />
</Suspense>
</div>
) : (
<Suspense>
<LeftPanel />
</Suspense>
)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To reduce duplicated code this should probably live inside the LeftPanel so the header and navigation can be re-used.


import { getHeaders } from './helpers';

const getSolarAssets = async (): Promise<any> => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we specify this type to get rid of the eslint issue?


const getSolarAssets = async (): Promise<any> => {
const path: URL = new URL(
'https://storage.googleapis.com/testing-gzipped-geojson/solar_power_plants.geojson'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably live behind our own domain, we can set up a simple proxy in Cloudflare to ensure it's properly cached and we get all the metrics. It has default support for buckets and such.

Comment on lines +11 to +14
const requestOptions: RequestInit = {
method: 'GET',
headers: await getHeaders(path),
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Get is the default method so it does not need to be specified.


const response = await fetch(path, requestOptions);
const result = await response.json();
console.log('res123', result);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rouge logging.

Comment on lines +123 to +157
export const getFilteredSolarAssets = (
searchTerm: string,
solarAssets: SolarAssetRowType[]
): SolarAssetRowType[] => {
if (!searchTerm) {
return [];
}

const searchLower = searchTerm.toLowerCase();

return solarAssets.filter(
(asset) =>
asset.name.toLowerCase().includes(searchLower) ||
(asset.country && asset.country.toLowerCase().includes(searchLower)) ||
(asset.capacity && asset.capacity.toLowerCase().includes(searchLower)) ||
(asset.status && asset.status.toLowerCase().includes(searchLower))
);
};

// Combined search function that returns both zone and solar asset results
export const getCombinedSearchResults = (
searchTerm: string,
zoneData: Record<string, ZoneRowType>,
solarAssets: SolarAssetRowType[]
): SearchResultType[] => {
if (!searchTerm) {
return [];
}

const filteredZones = getFilteredList(searchTerm, zoneData);
const filteredSolarAssets = getFilteredSolarAssets(searchTerm, solarAssets);

// Combine results - zones first, then solar assets
return [...filteredZones, ...filteredSolarAssets];
};
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The above function should just be updated to include these directly as we are duplicating logic and doing work twice now, as well as unpacking and re-packing two potentially large arrays. If we add more assets like wind turbines in the future this is going to be a real problem.

Comment on lines +138 to 140
renderFullHeader={() => (
<ZoneHeader zoneId={zoneId} isEstimated={isEstimatedForHeader} />
)}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lambda or anonymous functions declared inside the components are a big No No in react and will cause re-render issues.

It either need to be moved up inside the component and wrapped inside a useCallback or declared outside the component.

Comment on lines 159 to +164
if (zoneDataStatus === ZoneDataStatus.NO_INFORMATION) {
return <NoInformationMessage />;
}
if (zoneDataStatus === false) {
return <NoInformationMessage />;
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be combined with the above check.

Comment on lines +52 to +56
{renderFullHeader
? renderFullHeader()
: // Render built-in header only if title is provided (as a proxy for wanting the built-in header)
// Or if custom start/end content is provided, as they need a header bar.
(title || customHeaderStartContent || customHeaderEndContent) && (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
{renderFullHeader
? renderFullHeader()
: // Render built-in header only if title is provided (as a proxy for wanting the built-in header)
// Or if custom start/end content is provided, as they need a header bar.
(title || customHeaderStartContent || customHeaderEndContent) && (
{renderFullHeader?.() ??
// Render built-in header only if title is provided (as a proxy for wanting the built-in header)
// Or if custom start/end content is provided, as they need a header bar.
(title || customHeaderStartContent || customHeaderEndContent) && (

Comment on lines +104 to +112
{(() => {
if (isLoading) {
return <LoadingSpinner />;
}
if (error) {
return <div className="p-3 text-center text-red-500 md:p-4">{error}</div>;
}
return children;
})()}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here about the anonymous/lambda function.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants