-
Notifications
You must be signed in to change notification settings - Fork 1k
[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
base: master
Are you sure you want to change the base?
Conversation
}); | ||
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
Show autofix suggestion
Hide autofix suggestion
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:
- Defining a new type or interface for the
properties
object. - Updating the type assertion on line 645 to use the new type instead of
any
.
-
Copy modified line R645
@@ -644,3 +644,3 @@ | ||
if (solarAssetFeature) { | ||
const properties = (solarAssetFeature.properties as Record<string, any>) || {}; | ||
const properties = (solarAssetFeature.properties as Record<string, unknown>) || {}; | ||
const assetInfo = { |
There was a problem hiding this 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...
{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> | ||
)} |
There was a problem hiding this comment.
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> => { |
There was a problem hiding this comment.
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' |
There was a problem hiding this comment.
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.
const requestOptions: RequestInit = { | ||
method: 'GET', | ||
headers: await getHeaders(path), | ||
}; |
There was a problem hiding this comment.
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); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Rouge logging.
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]; | ||
}; |
There was a problem hiding this comment.
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.
renderFullHeader={() => ( | ||
<ZoneHeader zoneId={zoneId} isEstimated={isEstimatedForHeader} /> | ||
)} |
There was a problem hiding this comment.
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.
if (zoneDataStatus === ZoneDataStatus.NO_INFORMATION) { | ||
return <NoInformationMessage />; | ||
} | ||
if (zoneDataStatus === false) { | ||
return <NoInformationMessage />; | ||
} |
There was a problem hiding this comment.
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.
{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) && ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{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) && ( |
{(() => { | ||
if (isLoading) { | ||
return <LoadingSpinner />; | ||
} | ||
if (error) { | ||
return <div className="p-3 text-center text-red-500 md:p-4">{error}</div>; | ||
} | ||
return children; | ||
})()} |
There was a problem hiding this comment.
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.
No description provided.