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

DEV -> TEST #2 #78

Merged
merged 78 commits into from
May 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
78 commits
Select commit Hold shift + click to select a range
e854a75
Renamed app to NERT
Jan 11, 2024
2551e3a
Updated repository to be cloned
Jan 11, 2024
4255574
[NERT-94] testing protected dev branch (#1)
oscar-ip Jan 22, 2024
f9e2e06
TEST: Create change in GitHub (#2)
JonTaylorBCGov2 Feb 2, 2024
6782b80
[NERT-104] updated code to seed first admin user in database (#3)
oscar-ip Feb 14, 2024
08b6a79
[NERT-53] database and postgis upgrade (#4)
oscar-ip Feb 21, 2024
7eebda1
[NERT-109] updated api node libs versions (#5)
oscar-ip Feb 23, 2024
1b11d72
[NERT-55] app dependencies upgrades/updates (#6)
oscar-ip Feb 27, 2024
4d99623
[NERT-103] app container runs with upgrades/updates (#7)
oscar-ip Feb 27, 2024
009cc8e
Nert 118 (#8)
popkinj Feb 28, 2024
d97c54f
[NERT-43] app footer, header and lookand feel changes plus more chang…
oscar-ip Feb 29, 2024
3e816f4
[NERT-61] Initial look at mui styles plus more changes related to the…
oscar-ip Mar 1, 2024
6a3a957
Nert 46b (#11)
popkinj Mar 1, 2024
59707e0
Nert 61a (#12)
oscar-ip Mar 4, 2024
8b00570
NERT-61 completed replacement of mui styles (#13)
oscar-ip Mar 5, 2024
3f17daf
NodeJS Memory Optimizations (#14)
popkinj Mar 5, 2024
2c7da0d
Nert 99 - Deprecating Moment.js (#15)
popkinj Mar 5, 2024
9af8754
NERT-200 app is now running on react 18 (#16)
oscar-ip Mar 7, 2024
f7e1002
NERT-214 Authenticated List View collapsible sections implemented (#17)
oscar-ip Mar 11, 2024
334c051
NERT-200a fixed area map bounds calculations, broke somehow while upg…
oscar-ip Mar 12, 2024
16cc5f7
NERT-200b fixed typescript error with useParams, updated readme to re…
oscar-ip Mar 13, 2024
d861c05
NERT-212-216 Auth List View paged table and export (#20)
oscar-ip Mar 17, 2024
01b7fdf
Nert 98 - New Map (#21)
popkinj Mar 19, 2024
15680bd
NERT-217 archive/unarchive UI functionality added for auth users (#22)
oscar-ip Mar 19, 2024
33837d0
NERT-208 filters added UI functionality to authorized users list view…
oscar-ip Mar 22, 2024
fdf64a2
NERT-208a fixed filters date functionality, externalized paged table …
oscar-ip Mar 25, 2024
9e0e59a
Nert 67 (#25)
popkinj Mar 26, 2024
8647567
NERT-249 project and plan state machines implemented (#26)
oscar-ip Mar 26, 2024
f34ab6d
NERT-163 initial data model changes, auth list view updates, api lint…
oscar-ip Mar 30, 2024
5962971
MapLibre in Main App (#28)
popkinj Apr 2, 2024
c249617
NERT-211 Non auth list view for projects and plans now working (#29)
oscar-ip Apr 3, 2024
2b9ec1e
Fixing the no token bug (#30)
popkinj Apr 3, 2024
448b52c
NERT-280 Auth list view project table info dialog and other changes (…
oscar-ip Apr 8, 2024
e625783
NERT-280a Auth list view plan table info dialog added (#32)
oscar-ip Apr 8, 2024
790e048
NERT-275 Public list view project and plan table info dialog added (#33)
oscar-ip Apr 9, 2024
93ea074
Nert 277 - Layer Switcher (#34)
popkinj Apr 9, 2024
9c5d5ce
Nert 257 - Map control for layer switcher to match Leaflet control. (…
popkinj Apr 10, 2024
99e6a94
NERT-203 Public list view project and plan removed archived and NERT-…
oscar-ip Apr 10, 2024
bf8722a
NERT-225 Delete drafts UI piece is now implemented, fixed draft creat…
oscar-ip Apr 12, 2024
a3f4f63
Nert 253 - Styled and Clustered Plans and Projects (#38)
popkinj Apr 12, 2024
e899237
NERT-218 My List View UI mostly completed, API/DB model updates (#39)
oscar-ip Apr 16, 2024
a6faf75
Nert 278 (#40)
popkinj Apr 16, 2024
223a514
NERT-220 API/DB model rolled back latest update (#41)
oscar-ip Apr 16, 2024
39371dd
NERT-218 Archived projects plans now not showing for non admin users …
oscar-ip Apr 17, 2024
bd9e688
NERT-218 fixed issue with react duplicate keys (#43)
oscar-ip Apr 17, 2024
005dd76
New Base Layers (#44)
popkinj Apr 18, 2024
bfe9275
Isolating projects and plans (#45)
popkinj Apr 19, 2024
40c2cc0
NERT-46 simplified default routing to main map (#46)
oscar-ip Apr 19, 2024
88ca723
NERT-228 fixed issues introduced in the project router for My List an…
oscar-ip Apr 20, 2024
6ffb5f1
Nert 295 - Hover Project/Plans (#48)
popkinj Apr 23, 2024
ce452bf
Nert 272 - Styling for Well Sites and Well Activities (#49)
popkinj Apr 24, 2024
e944600
NERT-231 Migrated react router from v5 to v6 (#50)
oscar-ip Apr 24, 2024
c6fd75d
NERT-328 Create project and draft now using v6 data router api (#51)
oscar-ip Apr 26, 2024
ea93d5f
Geojson upload feature (#52)
popkinj Apr 29, 2024
13b74a5
NERT-219 All project/plan lists updated labels to use externalized la…
oscar-ip Apr 29, 2024
66ce9c5
Deprecating unsupported spatial formats. (#54)
popkinj Apr 29, 2024
3ba2107
Upload GeoJSON files to Maplibre Map within the project creation page…
popkinj May 6, 2024
f6ca674
NERT-326 Basic Project creation implemented (#56)
oscar-ip May 7, 2024
589efe2
Fix for Dropzone bug (#57)
popkinj May 7, 2024
8327e9b
Here is our custom community layer (#58)
popkinj May 8, 2024
bce4e40
Api unit tests (#59)
KjartanE May 8, 2024
eee576e
NERT-313 Basic Project view for non auth users implemented (#60)
oscar-ip May 9, 2024
3c2a4af
NERT-326 Project Create confirmation and fixes (#61)
oscar-ip May 10, 2024
3670e17
NERT-27 updated identity providers credentials (#62)
oscar-ip May 13, 2024
9f8ee46
NERT-304 removed treatments, other minor changes (#64)
oscar-ip May 15, 2024
87532e8
NERT-27: Update OpenShift Pipeline (#63)
KjartanE May 15, 2024
e5f43a3
NERT-22 pipeline readme files update (#66)
oscar-ip May 16, 2024
42ac489
Update Node 14-20, format/lint fix (#65)
KjartanE May 16, 2024
414404b
NERT-22a dev pipeline work (#67)
oscar-ip May 17, 2024
1373e47
NERT-22b react env vars (#68)
oscar-ip May 22, 2024
ea728ec
Nert 288 - Masking of sensitive projects (#69)
popkinj May 22, 2024
fc9a46e
NERT-23 lint issues, disabling non functional features in preparation…
oscar-ip May 22, 2024
edb42ff
FIX App Tests (#70)
KjartanE May 22, 2024
e95ae12
Update: Eslint/Prettier (#72)
KjartanE May 22, 2024
fe4c6ae
NERT-23a preparing for test env, fixed issue with mp4 link (#73)
oscar-ip May 22, 2024
1046396
NERT-23a linking pods in openshift (#75)
oscar-ip May 23, 2024
0aec4b7
Nert 358 (#77)
popkinj May 23, 2024
f415432
Merge remote-tracking branch 'origin/test' into dev
KjartanE May 24, 2024
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
20 changes: 18 additions & 2 deletions app/src/components/attachments/ImageUpload.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,11 @@
}
}
};
// Fixing a lame typescript error
const centerText = 'center' as const;
const fitObject = 'cover' as const;

Check warning on line 56 in app/src/components/attachments/ImageUpload.tsx

View check run for this annotation

Codecov / codecov/patch

app/src/components/attachments/ImageUpload.tsx#L55-L56

Added lines #L55 - L56 were not covered by tests

// Styles for the component
const styles = {
default: {
border: '3px dashed #0003',
Expand All @@ -62,6 +67,17 @@
borderRadius: '25px',
cursor: 'pointer',
overflow: 'hidden'
},
text: {
color: '#0003',
fontSize: '1.2rem',
margin: '1rem',
textAlign: centerText
},
image: {
height: '200px',
width: '100%',
objectFit: fitObject
}
};

Expand All @@ -74,9 +90,9 @@
onDragLeave={handleMouseLeave}
onDrop={handleDrop}>
{image ? (
<img src={image} alt="uploaded" style={{ height: '200px', width: '200px' }} />
<img src={image} alt="uploaded" style={styles.image} />
) : (
<div>{hoverText}</div>
<div style={styles.text}>{hoverText}</div>
)}
</div>
);
Expand Down
91 changes: 87 additions & 4 deletions app/src/components/map/MapContainer2.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
centroids?: boolean;
mask?: null | number; // Store what mask just changed
maskState?: boolean[]; // Store which features are masked
activeFeatureState?: any; // Store which feature is active
}

const MAPTILER_API_KEY = process.env.REACT_APP_MAPTILER_API_KEY;
Expand Down Expand Up @@ -253,14 +254,43 @@
map.getSource('mask').setData(maskGeojson);
};

let hoverStateMarkerPolygon: boolean | any = false;
const checkFeatureState = (featureState: any) => {
if (!map.getSource('markers')) return; // Exit if markers are not initialized

if (hoverStateMarkerPolygon) {
map.setFeatureState(
{
source: 'markers',
id: hoverStateMarkerPolygon.id
},
{ hover: false }
);
}

// If there is a feature state, set the hover state
if (featureState[0]) {
map.setFeatureState(
{
source: 'markers',
id: featureState[0].id
},
{ hover: true }
);
}

hoverStateMarkerPolygon = featureState[0] || false;
};

const initializeMap = (
mapId: string,
center: any = [-124, 57],
zoom = 6,
features?: any, // There's no features when first creating a record
layerVisibility?: any,
centroids = false,
tooltipState?: any
tooltipState?: any,
activeFeatureState?: any
) => {
const { boundary, wells, projects, plans, wildlife, indigenous } = layerVisibility;

Expand Down Expand Up @@ -411,7 +441,6 @@
map.addSource('markers', {
type: 'geojson',
data: markerGeoJSON as FeatureCollection,
promoteId: 'id',
cluster: centroids ? true : false,
clusterRadius: 50,
clusterMaxZoom: 12
Expand Down Expand Up @@ -479,9 +508,48 @@
visibility: 'visible'
},
paint: {
'fill-color': 'rgba(245,149,66,0.8)'
'fill-color': [
'case',
['boolean', ['feature-state', 'hover'], false],
'rgba(250,191,120,1)',
'rgba(250,191,120,0.5)'
]
}
});
// let hoverStateMarkerPolygon: boolean | any = false;
map
.on('mouseenter', 'markerPolygon', (e: any) => {
map.getCanvas().style.cursor = 'pointer';

checkFeatureState(activeFeatureState);
activeFeatureState[1](e.features[0]);

// console.log('entering index: ', e.features[0].id);
// if (activeFeatureState[0]) {
// activeFeatureState[1](e.features[0]);
// }

// hoverStateMarkerPolygon = e.features[0].id;
// map.setFeatureState(
// {
// source: 'markers',
// id: e.features[0].id
// },
// { hover: true }
// );
})
.on('mouseleave', 'markerPolygon', () => {
map.getCanvas().style.cursor = '';

activeFeatureState[1](null);
// map.setFeatureState(
// {
// source: 'markers',
// id: hoverStateMarkerPolygon
// },
// { hover: false }
// );
});

// Zoom in until cluster breaks apart.
map.on('click', 'markerClusters.points', (e: any) => {
Expand Down Expand Up @@ -526,7 +594,7 @@

/* Add popup for the points */
map.on('click', 'markerProjects.points', (e: any) => {
const prop = e.features![0].properties;

Check warning on line 597 in app/src/components/map/MapContainer2.tsx

View workflow job for this annotation

GitHub Actions / Running Linter

Forbidden non-null assertion

const html = makePopup(prop.name, prop.id, true);

Expand All @@ -542,7 +610,7 @@

/* Add popup for the points */
map.on('click', 'markerPlans.points', (e: any) => {
const prop = e.features![0].properties;

Check warning on line 613 in app/src/components/map/MapContainer2.tsx

View workflow job for this annotation

GitHub Actions / Running Linter

Forbidden non-null assertion

// TBD: Currently the /plans route is not available
// const html = makePopup(prop.name, prop.id, false);
Expand Down Expand Up @@ -795,6 +863,7 @@

const maskState = props.maskState || [];
const mask = props.mask || 0;
const activeFeatureState = props.activeFeatureState || [];

// Tooltip variables
const [tooltipVisible, setTooltipVisible] = useState(false);
Expand All @@ -816,7 +885,16 @@

// Update the map if the features change
useEffect(() => {
initializeMap(mapId, center, zoom, features, layerVisibility, centroids, tooltipState);
initializeMap(
mapId,
center,
zoom,
features,
layerVisibility,
centroids,
tooltipState,
activeFeatureState
);
}, [features]);

// Listen to layer changes
Expand All @@ -833,6 +911,11 @@
updateMasks(mask, maskState, features);
}, [maskState]);

// Listen for active feature changes
useEffect(() => {
checkFeatureState(activeFeatureState);
}, [activeFeatureState]);

return (
<div id={mapId} style={pageStyle}>
<div
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ export const ProjectGeneralInformationFormYupSchema = yup.object().shape({
})
});

const uploadImageStyles = {
marginTop: '23px'
};

/**
* Create project - General information section
*
Expand All @@ -69,8 +73,10 @@ const ProjectGeneralInformationForm: React.FC = () => {

return (
<Grid container spacing={3}>
<ImageUpload />
<Grid item xs={12} md={9}>
<div style={uploadImageStyles}>
<ImageUpload />
</div>
<Grid item xs={12} md={8}>
<Grid container spacing={3} direction="column">
<Grid item xs={12}>
<CustomTextField
Expand Down
62 changes: 52 additions & 10 deletions app/src/features/projects/components/ProjectLocationForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import Button from '@mui/material/Button';
import Checkbox from '@mui/material/Checkbox';
import FormControl from '@mui/material/FormControl';
import FormControlLabel from '@mui/material/FormControlLabel';
import FormGroup from '@mui/material/FormGroup';
import FormHelperText from '@mui/material/FormHelperText';
import FormLabel from '@mui/material/FormLabel';
import Grid from '@mui/material/Grid';
Expand All @@ -26,9 +27,10 @@ import IntegerSingleField from 'components/fields/IntegerSingleField';
import MapContainer from 'components/map/MapContainer2';
import { useFormikContext } from 'formik';
import { Feature } from 'geojson';
import React, { useState } from 'react';
import React, { useEffect, useState } from 'react';
import { handleGeoJSONUpload } from 'utils/mapBoundaryUploadHelpers';
import yup from 'utils/YupSchema';
import './styles/projectLocation.css';

export interface IProjectLocationForm {
location: {
Expand Down Expand Up @@ -82,9 +84,8 @@ const ProjectLocationForm: React.FC<IProjectLocationFormProps> = (props) => {

const [openUploadBoundary, setOpenUploadBoundary] = useState(false);

// Mask state array
const [maskState, setMaskState] = useState<boolean[]>(
values.location.geometry.map((feature) => feature.properties?.maskedLocation)
values.location.geometry.map((feature) => feature?.properties?.maskedLocation) || []
);

// Mask change indicator
Expand All @@ -95,7 +96,6 @@ const ProjectLocationForm: React.FC<IProjectLocationFormProps> = (props) => {
if (file?.name.includes('json')) {
handleGeoJSONUpload(file, 'location.geometry', formikProps);
}

return Promise.resolve();
};
};
Expand All @@ -121,6 +121,24 @@ const ProjectLocationForm: React.FC<IProjectLocationFormProps> = (props) => {
baselayer
};

/**
* State to share with the map to indicate which
* feature is selected or hovered over
*/
const [activeFeature, setActiveFeature] = useState<Feature | null>(null);

useEffect(() => {
console.log('active feature just changed', activeFeature);
}, [activeFeature]);

const featureStyle = {
parent: {
display: 'grid',
gridTemplateColumns: '1fr 1fr auto',
cursor: 'pointer'
}
};

const maskChanged = (event: React.ChangeEvent<HTMLInputElement>, index: number) => {
// Update the formik values
// @ts-ignore
Expand All @@ -137,6 +155,17 @@ const ProjectLocationForm: React.FC<IProjectLocationFormProps> = (props) => {
setMask(index);
};

// TODO: Connect these to the map state for active shapes
const mouseEnterListItem = (index: number) => {
console.log('mouse enter', index);
console.log(values.location.geometry[index]);
setActiveFeature(values.location.geometry[index]);
};
const mouseLeaveListItem = (index: number) => {
console.log('mouse leave', index);
setActiveFeature(null);
};

return (
<>
<Box mb={5} mt={0}>
Expand Down Expand Up @@ -292,18 +321,30 @@ const ProjectLocationForm: React.FC<IProjectLocationFormProps> = (props) => {
</Button>
</Box>

<Box>
<Box className="feature-box">
{/* Create a list element for each feature within values.location.geometry */}
{values.location.geometry.map((feature, index) => (
<div className="feature-list" key={index}>
<div
style={featureStyle.parent}
className={activeFeature?.id === feature?.id ? 'feature-item active' : 'feature-item'}
key={index}
onMouseEnter={() => mouseEnterListItem(index)}
onMouseLeave={() => mouseLeaveListItem(index)}>
<div className="feature-name">
{feature.properties?.siteName || `Area ${index + 1}`}
</div>
<div className="feature-size">{feature.properties?.areaHectares || 0} Ha</div>
<Checkbox
checked={feature.properties?.maskedLocation}
onChange={(event) => maskChanged(event, index)}
/>
<FormGroup>
<FormControlLabel
control={
<Checkbox
checked={feature.properties?.maskedLocation || false}
onChange={(event) => maskChanged(event, index)}
/>
}
label="Mask"
/>
</FormGroup>
</div>
))}
</Box>
Expand All @@ -315,6 +356,7 @@ const ProjectLocationForm: React.FC<IProjectLocationFormProps> = (props) => {
features={values.location.geometry}
mask={mask}
maskState={maskState}
activeFeatureState={[activeFeature, setActiveFeature]}
/>
</Box>
{errors?.location?.geometry && (
Expand Down
20 changes: 20 additions & 0 deletions app/src/features/projects/components/styles/projectLocation.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.feature-item {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
padding: 0 10px;
border: 0.5px solid #ccc;
background-color: #f9f9f9;
/* &:hover {
background-color: #e2fbff;
} */
&.active {
background-color: #e2fbff;
}
}

.feature-box > :first-child {
border-top-left-radius: 5px;
border-top-right-radius: 5px;
}
12 changes: 11 additions & 1 deletion app/src/utils/mapBoundaryUploadHelpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,17 @@ export const handleGeoJSONUpload = async <T>(
setFieldError(name, 'Only Polygon or MultiPolygon features are supported.');
return;
}
setFieldValue(name, [...get(values, name), ...geojsonWithAttributes.features]);

// Merge the new features with the existing features
const allFeatures = [...get(values, name), ...geojsonWithAttributes.features];

// Recalculate the IDs for all features
const allFeaturesWithIds = allFeatures.map((feature, index) => {
feature.id = index;
return feature;
});

setFieldValue(name, allFeaturesWithIds);
} catch (error) {
setFieldError(name, 'Error uploading your GeoJSON file, please check the file and try again.');
}
Expand Down
Loading