Skip to content
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

bring in ui polish with latest code + add interactions between map and table #132

Merged
merged 4 commits into from
Mar 9, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion asset_dashboard/static/css/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,9 @@ input[type="checkbox"] {
}

.map-container {
height: 650px;
height: 85vh;
}

.map-thumbnail {
height: 40vh;
}
Binary file modified asset_dashboard/static/images/favicon-16x16.png
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified asset_dashboard/static/images/favicon-32x32.png
100755 → 100644
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified asset_dashboard/static/images/favicon.ico
100755 → 100644
Binary file not shown.
Binary file added asset_dashboard/static/images/fpdcc-logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion asset_dashboard/static/js/PortfolioPlanner.js
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ class PortfolioPlanner extends React.Component {
<CSVLink
data={this.state.portfolio.projects}
filename={`CIP-${this.getDate()}`}
className='btn btn-primary mx-auto'
className='btn btn-info mx-auto'
>
Export as CSV
</CSVLink>
Expand Down
8 changes: 4 additions & 4 deletions asset_dashboard/static/js/components/BaseTable.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { useTable, usePagination, useSortBy } from 'react-table'

const BaseTable = ({ rows = [], columns, getTrProps = props => props, rowClassNames, sizeOfPage=15, pageSizeIncrements=[15, 30, 45] }) => {
const BaseTable = ({ rows = [], columns, getTrProps = props => props, rowClassNames, cellClassNames, sizeOfPage=15, pageSizeIncrements=[15, 30, 45] }) => {

const data = React.useMemo(
() => rows.map((row) => {
Expand Down Expand Up @@ -50,7 +50,7 @@ const BaseTable = ({ rows = [], columns, getTrProps = props => props, rowClassNa
key={i} className={rowClassNames ? `${rowClassNames} cursor-pointer` : 'cursor-pointer'}>
{row.cells.map(cell => {
return (
<td {...cell.getCellProps()} className='text-center'>
<td {...cell.getCellProps()} className={`${cellClassNames && cellClassNames} text-center`}>
{cell.render('Cell')}
</td>
)
Expand All @@ -64,9 +64,9 @@ const BaseTable = ({ rows = [], columns, getTrProps = props => props, rowClassNa

<div className="row container" aria-label="Pagination for all potential projects.">
<div className="d-flex col align-items-center ml-2">
<small className="text-muted">Pages {pageIndex + 1} of {pageOptions.length > 0 ? pageOptions.length : 1 }</small>
<small className="text-muted mb-3">Pages {pageIndex + 1} of {pageOptions.length > 0 ? pageOptions.length : 1 }</small>
</div>
<ul className="pagination col d-flex align-items-center mb-0">
<ul className="pagination col d-flex align-items-center justify-content-center">
<li className="page-item">
<button onClick={() => gotoPage(0)} disabled={!canPreviousPage} className="btn btn-light btn-sm">
{'<<'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,16 @@ import clip from 'turf-clip'
import * as turf from '@turf/turf'
import EditControl from './EditControl'

export default function MapClipper({ geoJson, onClipped }) {
/*
Allows the selection of multiple geometries at once. Also clips
LineStrings based on the bounds of the drawn geometry area.
*/
export default function GeometrySelector({ geoJson, onGeometriesSelected }) {
const [drawnGeometries, setDrawnGeometries] = useState(null)

useEffect(() => {
if (drawnGeometries) {
clipGeometries(drawnGeometries)
selectGeometries(drawnGeometries)
}
}, [drawnGeometries])

Expand Down Expand Up @@ -60,7 +64,8 @@ export default function MapClipper({ geoJson, onClipped }) {
intersect with the drawnGeometries.
A LineString would be a trail that can be clipped.
The remaining types would be like a building or structure, etc
that should be treated as an entire entity and not clipped. */
that should be treated as an entire entity and not clipped, but entirely selected.
*/
function separateGeometryTypes() {
const lineStringFeatureTypes = []
const allOtherFeatureTypes = []
Expand Down Expand Up @@ -103,7 +108,7 @@ export default function MapClipper({ geoJson, onClipped }) {
return []
}

function clipGeometries(geometries) {
function selectGeometries(geometries) {
const [lineStringFeatureCollection, allOtherTypesFeatureCollection] = separateGeometryTypes()

const bounds = turf.featureCollection(Object.values(geometries))
Expand All @@ -115,11 +120,11 @@ export default function MapClipper({ geoJson, onClipped }) {
const finalFeatureCollection = turf.featureCollection(intersectingFeatures.concat(clippedFeatures))

if (finalFeatureCollection.features.length > 0) {
onClipped(finalFeatureCollection)
onGeometriesSelected(finalFeatureCollection)
} else {
// No features exist, which means they were deleted.
// Send back null so that the caller has no clipped geometries.
onClipped(null)
// Send back null so that the caller has no geometries.
onGeometriesSelected(null)
}
}

Expand Down
24 changes: 24 additions & 0 deletions asset_dashboard/static/js/components/map_utils/ShowPopup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React, { useEffect } from 'react'
import { useMap } from 'react-leaflet'

export default function ShowPopup({ geojson }) {
const map = useMap()

useEffect(() => {
map.eachLayer((layer) => {
if (layer.feature == geojson) {
layer.openPopup()

// Make the layer appear selected.
layer.setStyle({
fillColor: '#3388ff',
fillOpacity: '0.2',
color: '#3388ff',
weight: '4'
})
}
})
}, [geojson])

return null
}
36 changes: 36 additions & 0 deletions asset_dashboard/static/js/components/map_utils/bindPopup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react'
import ReactDOMServer from 'react-dom/server'

function Popup({ feature }) {
const properties = feature.properties
return (
<>
{properties &&
<div>
<h6>Asset Info</h6>
<ul className='list-group list-group-flush'>
<li className='list-group-item'>
<strong>ID:</strong> {properties.asset_id ? properties.asset_id : properties.identifier }
</li>
<li className='list-group-item'>
<strong>Name:</strong> {properties.asset_name ? properties.asset_name : properties.name }
</li>
{properties.asset_type
&& <li className='list-group-item'>
<strong>Asset Type:</strong> {properties.asset_type}
</li>
}
</ul>
</div>
}
</>
)
}

export default function bindPopup(feature, layer, autoShow=false) {
const popupContent = ReactDOMServer.renderToString(
<Popup feature={feature} />
)

layer.bindPopup(popupContent)
}
54 changes: 39 additions & 15 deletions asset_dashboard/static/js/components/maps/ListAssetsMap.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import BaseMap from './BaseMap'
import { GeoJSON } from 'react-leaflet'
import zoomToExistingGeometries from '../map_utils/zoomToExistingGeometries'
import circleMarker from '../map_utils/circleMarker'
import ReactTable from '../BaseTable'
import existingAssetsColumns from '../table_utils/existingAssetsColumns'
import bindPopup from '../map_utils/bindPopup'

function ListAssetsMap(props) {

Expand All @@ -13,21 +16,42 @@ function ListAssetsMap(props) {
}

return (
<div className='map-container'>
<BaseMap
center={[41.8781, -87.6298]}
zoom={11}
whenCreated={onMapCreated}>
{
props?.assets &&
<GeoJSON
data={props.assets}
style={{color: 'green'}}
pointToLayer={circleMarker}
/>
}
</BaseMap>
</div>
<>
{
props?.assets &&
<div className=''>
<div className='row'>
<div className='col-4 m-3'>
<div className="d-flex align-items-center justify-content-between m-2">
<h3>Phase Assets</h3>
<a href={`${window.location.href}assets`} class="text-info lead">Edit Assets ></a>
</div>
<div className='map-thumbnail'>
<BaseMap
center={[41.8781, -87.6298]}
zoom={11}
whenCreated={onMapCreated}>
<GeoJSON
data={props.assets}
style={{color: 'green'}}
pointToLayer={circleMarker}
onEachFeature={bindPopup}
/>
</BaseMap>
</div>
</div>
<div className='col m-3'>
<ReactTable
rows={props.assets.features}
columns={React.useMemo(() => existingAssetsColumns(), [])}
pageSizeIncrements={[10]}
sizeOfPage={10}
/>
</div>
</div>
</div>
}
</>
)
}

Expand Down
Loading