From 3d65a9729f8c6d6696b21b90835293b81dc0a3ea Mon Sep 17 00:00:00 2001 From: stdavis Date: Tue, 5 Nov 2024 15:54:26 -0700 Subject: [PATCH 1/6] fix: make equipment type values match domain values --- src/components/method/Equipment.jsx | 8 +++---- src/components/method/Equipment.stories.jsx | 2 +- src/hooks/samplingEventContext.jsx | 25 +++++++++++---------- 3 files changed, 18 insertions(+), 17 deletions(-) diff --git a/src/components/method/Equipment.jsx b/src/components/method/Equipment.jsx index ccc4128f..40f8cbc5 100644 --- a/src/components/method/Equipment.jsx +++ b/src/components/method/Equipment.jsx @@ -7,9 +7,9 @@ import NumericInputValidator from '../NumericInputValidator.jsx'; const ACTIVE = 'active'; export const EQUIPMENT_TYPES = { - BACKPACK: 'backpack', - CANOEBARGE: 'canoebarge', - RAFTBOAT: 'raftboat', + BACKPACK: 'Backpack', + CANOEBARGE: 'Canoe/Barge', + RAFTBOAT: 'Raft/Boat', }; export const CATHODE_TYPES = { BOAT: 'Boat', @@ -87,7 +87,7 @@ function Equipment({ state, onChange, addNew, remove, isLast, isFirst }) { const value = c.accessorKey === fieldNamesAN.EQUIPMENT_ID ? state.equipment[fieldNamesEQ.EQUIPMENT_ID] : null; return [c.accessorKey, value]; - }) + }), ); } diff --git a/src/components/method/Equipment.stories.jsx b/src/components/method/Equipment.stories.jsx index 073b8ad3..a3291c6b 100644 --- a/src/components/method/Equipment.stories.jsx +++ b/src/components/method/Equipment.stories.jsx @@ -16,7 +16,7 @@ export const Default = () => { const [state, setState] = useState({ equipment: { [fieldNames.EVENT_ID]: getGUID(), - [fieldNames.TYPE]: 'backpack', + [fieldNames.TYPE]: 'Backpack/Canoe', [fieldNames.EQUIPMENT_ID]: getGUID(), [fieldNames.MODEL]: null, [fieldNames.ARRAY_TYPE]: null, diff --git a/src/hooks/samplingEventContext.jsx b/src/hooks/samplingEventContext.jsx index f5ce16dc..1403bfbd 100644 --- a/src/hooks/samplingEventContext.jsx +++ b/src/hooks/samplingEventContext.jsx @@ -3,6 +3,7 @@ import React from 'react'; import { useImmerReducer } from 'use-immer'; import config from '../config'; import getGUID from '../helpers/getGUID'; +import { EQUIPMENT_TYPES } from '../components/method/Equipment.jsx'; const SamplingEventContext = React.createContext(); export const actionTypes = { @@ -34,7 +35,7 @@ export const actionTypes = { function getNewEquipment(eventId) { return { [config.fieldNames.equipment.EVENT_ID]: eventId, - [config.fieldNames.equipment.TYPE]: 'backpack', + [config.fieldNames.equipment.TYPE]: EQUIPMENT_TYPES.BACKPACK, [config.fieldNames.equipment.EQUIPMENT_ID]: getGUID(), [config.fieldNames.equipment.MODEL]: null, [config.fieldNames.equipment.ARRAY_TYPE]: null, @@ -242,7 +243,7 @@ const reducer = (draft, action) => { case actionTypes.ADD_EQUIPMENT: draft[config.tableNames.equipment].push( - getNewEquipment(draft[config.tableNames.samplingEvents].attributes[config.fieldNames.samplingEvents.EVENT_ID]) + getNewEquipment(draft[config.tableNames.samplingEvents].attributes[config.fieldNames.samplingEvents.EVENT_ID]), ); break; @@ -271,8 +272,8 @@ const reducer = (draft, action) => { getNewFish( draft[config.tableNames.samplingEvents].attributes[config.fieldNames.samplingEvents.EVENT_ID], newPass, - null - ) + null, + ), ); break; @@ -283,32 +284,32 @@ const reducer = (draft, action) => { getNewFish( draft[config.tableNames.samplingEvents].attributes[config.fieldNames.samplingEvents.EVENT_ID], action.payload, - draft[config.tableNames.fish] - ) + draft[config.tableNames.fish], + ), ); break; case actionTypes.REMOVE_FISH: draft[config.tableNames.fish] = draft[config.tableNames.fish].filter( - (fish) => fish[config.fieldNames.fish.FISH_ID] !== action.payload + (fish) => fish[config.fieldNames.fish.FISH_ID] !== action.payload, ); draft[config.tableNames.tags] = draft[config.tableNames.tags].filter( - (tag) => tag[config.fieldNames.tags.FISH_ID] !== action.payload + (tag) => tag[config.fieldNames.tags.FISH_ID] !== action.payload, ); draft[config.tableNames.health] = draft[config.tableNames.health].filter( - (health) => health[config.fieldNames.health.FISH_ID] !== action.payload + (health) => health[config.fieldNames.health.FISH_ID] !== action.payload, ); draft[config.tableNames.diet] = draft[config.tableNames.diet].filter( - (diet) => diet[config.fieldNames.diet.FISH_ID] !== action.payload + (diet) => diet[config.fieldNames.diet.FISH_ID] !== action.payload, ); break; case actionTypes.UPDATE_FISH: { const updateFishIndex = draft[config.tableNames.fish].findIndex( - (f) => f[config.fieldNames.fish.FISH_ID] === action.meta + (f) => f[config.fieldNames.fish.FISH_ID] === action.meta, ); draft[config.tableNames.fish][updateFishIndex] = { ...draft[config.tableNames.fish][updateFishIndex], @@ -319,7 +320,7 @@ const reducer = (draft, action) => { } case actionTypes.UPDATE_HEALTH: { const updateHealthIndex = draft[config.tableNames.health].findIndex( - (f) => f[config.fieldNames.fish.FISH_ID] === action.meta + (f) => f[config.fieldNames.fish.FISH_ID] === action.meta, ); if (updateHealthIndex === -1) { From 9df4c3fac8d592419ef1ad805c0977e05765b088 Mon Sep 17 00:00:00 2001 From: "ugrc-release-bot[bot]" <113075024+ugrc-release-bot[bot]@users.noreply.github.com> Date: Tue, 5 Nov 2024 22:58:01 +0000 Subject: [PATCH 2/6] chore: release v2.4.6-0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- src/config.js | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 8624ae34..edecf984 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"2.4.5"} +{".":"2.4.6-0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 4fd0b6af..5afa4482 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.4.6-0](https://github.com/agrc/electrofishing/compare/v2.4.5...v2.4.6-0) (2024-11-05) + + +### Bug Fixes + +* make equipment type values match domain values ([3d65a97](https://github.com/agrc/electrofishing/commit/3d65a9729f8c6d6696b21b90835293b81dc0a3ea)) + ## [2.4.5](https://github.com/agrc/electrofishing/compare/v2.4.4...v2.4.5) (2024-10-29) diff --git a/package-lock.json b/package-lock.json index 42124940..09bc33ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "electrofishing", - "version": "2.4.5", + "version": "2.4.6-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "electrofishing", - "version": "2.4.5", + "version": "2.4.6-0", "hasInstallScript": true, "dependencies": { "@tanstack/react-table": "^8.20.5", diff --git a/package.json b/package.json index a1aef15a..0153d575 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electrofishing", - "version": "2.4.5", + "version": "2.4.6-0", "scripts": { "build:stage": "export VITE_BUILD=stage && npm run build:sw && vite build", "build:sw": "esbuild src/ServiceWorker.js --bundle --outfile=public/ServiceWorker.js --define:process.env.VITE_FIREBASE_CONFIG=$(npx dotenv -p VITE_FIREBASE_CONFIG)", diff --git a/src/config.js b/src/config.js index a39456d2..5a280324 100644 --- a/src/config.js +++ b/src/config.js @@ -191,7 +191,7 @@ const config = { // version: String // The app version number. - version: '2.4.5', // x-release-please-version + version: '2.4.6-0', // x-release-please-version // coordTypes: {key:String} // Coordinate types as used in app/SettingsDialog From c269badb2f7151b07654ea635f81e032c47f6ce5 Mon Sep 17 00:00:00 2001 From: stdavis Date: Tue, 5 Nov 2024 16:52:50 -0700 Subject: [PATCH 3/6] chore: prevent multiple calls to connectAuthEmulator in dev --- src/hooks/useAuthentication.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hooks/useAuthentication.js b/src/hooks/useAuthentication.js index 562cce47..cf5d55b5 100644 --- a/src/hooks/useAuthentication.js +++ b/src/hooks/useAuthentication.js @@ -54,7 +54,7 @@ export default function useAuthentication() { initServiceWorker(); - if (import.meta.env.VITE_BUILD === 'development') { + if (import.meta.env.VITE_BUILD === 'development' && !authRef.current.emulatorConfig) { // comment out this and the auth config in firebase.json to hit utahid directly connectAuthEmulator(authRef.current, 'http://127.0.0.1:9099'); } From 895ca1106ea975b96c8d6864a79cd2ac5d79e7c1 Mon Sep 17 00:00:00 2001 From: stdavis Date: Tue, 5 Nov 2024 17:06:40 -0700 Subject: [PATCH 4/6] feat: add data submitter to sampling event data Closes #239 --- src/components/location/Location.jsx | 16 ++++++++++++++-- src/config.js | 1 + src/hooks/samplingEventContext.jsx | 1 + 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/components/location/Location.jsx b/src/components/location/Location.jsx index 01a743eb..1b498138 100644 --- a/src/components/location/Location.jsx +++ b/src/components/location/Location.jsx @@ -10,6 +10,7 @@ import StartDistDirGeoDef from './StartDistDirGeoDef.jsx'; import StartEndGeoDef from './StartEndGeoDef.jsx'; import Station from './Station.jsx'; import VerifyMap from './VerifyMap.jsx'; +import useAuthentication from '../../hooks/useAuthentication'; // successfullyVerifiedMsg: String // message displayed on the verify location button after success @@ -36,6 +37,17 @@ const Location = () => { const [startEndParams, setStartEndParams] = useState(emptyStartEndParams); const [startDistDirParams, setStartDistDirParams] = useState(emptyStartDistDirParams); const [currentGeoDef, setCurrentGeoDef] = useState(START_END); + const { user } = useAuthentication(); + + useEffect(() => { + if (user) { + eventDispatch({ + type: actionTypes.LOCATION, + meta: fieldNames.SUBMITTER, + payload: user.email, + }); + } + }, [eventDispatch, user]); const path = useRef(null); const geometry = eventState[config.tableNames.samplingEvents].geometry; @@ -198,7 +210,7 @@ const Location = () => { paths.push( path.map(function (c) { return [c[1], c[0]]; - }) + }), ); }); returnData.path = paths; @@ -344,7 +356,7 @@ const Location = () => { actionTypes.LOCATION, config.tableNames.samplingEvents, fieldName, - parser + parser, ); }; diff --git a/src/config.js b/src/config.js index 5a280324..6bce2126 100644 --- a/src/config.js +++ b/src/config.js @@ -37,6 +37,7 @@ const fieldNames = { WEATHER: 'WEATHER', PURPOSE: 'SURVEY_PURPOSE', OBSERVERS: 'OBSERVERS', + SUBMITTER: 'SUBMITTER', }, equipment: { EVENT_ID: fldEVENT_ID, diff --git a/src/hooks/samplingEventContext.jsx b/src/hooks/samplingEventContext.jsx index 1403bfbd..ef476a45 100644 --- a/src/hooks/samplingEventContext.jsx +++ b/src/hooks/samplingEventContext.jsx @@ -153,6 +153,7 @@ const getBlankState = () => { [config.fieldNames.samplingEvents.STATION_ID]: null, [config.fieldNames.samplingEvents.SEGMENT_LENGTH]: null, [config.fieldNames.samplingEvents.NUM_PASSES]: 1, + [config.fieldNames.samplingEvents.SUBMITTER]: null, }, geometry: null, }, From fc658cf252ee0b0cecdb39e82d9f1a7113acf5c7 Mon Sep 17 00:00:00 2001 From: "ugrc-release-bot[bot]" <113075024+ugrc-release-bot[bot]@users.noreply.github.com> Date: Wed, 6 Nov 2024 00:07:24 +0000 Subject: [PATCH 5/6] chore: release v2.5.0-0 --- .release-please-manifest.json | 2 +- CHANGELOG.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- src/config.js | 2 +- 5 files changed, 12 insertions(+), 5 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index edecf984..a61de1c5 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1 +1 @@ -{".":"2.4.6-0"} +{".":"2.5.0-0"} diff --git a/CHANGELOG.md b/CHANGELOG.md index 5afa4482..02d77fb9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## [2.5.0-0](https://github.com/agrc/electrofishing/compare/v2.4.6-0...v2.5.0-0) (2024-11-06) + + +### Features + +* add data submitter to sampling event data ([895ca11](https://github.com/agrc/electrofishing/commit/895ca1106ea975b96c8d6864a79cd2ac5d79e7c1)), closes [#239](https://github.com/agrc/electrofishing/issues/239) + ## [2.4.6-0](https://github.com/agrc/electrofishing/compare/v2.4.5...v2.4.6-0) (2024-11-05) diff --git a/package-lock.json b/package-lock.json index 09bc33ac..0a2dfef2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "electrofishing", - "version": "2.4.6-0", + "version": "2.5.0-0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "electrofishing", - "version": "2.4.6-0", + "version": "2.5.0-0", "hasInstallScript": true, "dependencies": { "@tanstack/react-table": "^8.20.5", diff --git a/package.json b/package.json index 0153d575..93b2db15 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "electrofishing", - "version": "2.4.6-0", + "version": "2.5.0-0", "scripts": { "build:stage": "export VITE_BUILD=stage && npm run build:sw && vite build", "build:sw": "esbuild src/ServiceWorker.js --bundle --outfile=public/ServiceWorker.js --define:process.env.VITE_FIREBASE_CONFIG=$(npx dotenv -p VITE_FIREBASE_CONFIG)", diff --git a/src/config.js b/src/config.js index 6bce2126..b3f59d73 100644 --- a/src/config.js +++ b/src/config.js @@ -192,7 +192,7 @@ const config = { // version: String // The app version number. - version: '2.4.6-0', // x-release-please-version + version: '2.5.0-0', // x-release-please-version // coordTypes: {key:String} // Coordinate types as used in app/SettingsDialog From fc5d8094b1dd1e6bbb76ae3bf5c8843589bc7753 Mon Sep 17 00:00:00 2001 From: stdavis Date: Wed, 6 Nov 2024 09:07:04 -0700 Subject: [PATCH 6/6] chore: add migration script for new field and data fixes --- scripts/migrations/migration_239.py | 55 +++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 scripts/migrations/migration_239.py diff --git a/scripts/migrations/migration_239.py b/scripts/migrations/migration_239.py new file mode 100644 index 00000000..79c7fc9d --- /dev/null +++ b/scripts/migrations/migration_239.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python +# * coding: utf8 * +""" +migration_239.py + +A module that adds a field for recording the submitter's email address in addition to fixing some values so that they match their associated domain values. + +Ref: https://github.com/agrc/electrofishing/issues/239 +""" + +import arcpy + +arcpy.env.workspace = r"..." + + +def add_field(): + field_name = "SUBMITTER" + table_name = "SamplingEvents" + describe = arcpy.da.Describe(table_name) + if field_name not in [field.name for field in describe["fields"]]: + print(f"adding {field_name} field") + arcpy.management.AddField( + table_name, + field_name=field_name, + field_type="TEXT", + field_length=255, + field_alias="Submitter Email", + ) + else: + print(f"{field_name} field already exists") + + +def fix_values(): + mappings = [ + ("backpack", "Backpack"), + ("canoebarge", "Canoe/Barge"), + ("raftboat", "Raft/Boat"), + ] + field_name = "TYPE" + print("fixing equipment type values...") + layer = arcpy.management.MakeFeatureLayer("Equipment", "equipment_layer") + + for old_value, new_value in mappings: + print(f"fixing {old_value} to {new_value}") + arcpy.management.SelectLayerByAttribute( + layer, "NEW_SELECTION", f"{field_name} = '{old_value}'" + ) + count = arcpy.management.GetCount(layer)[0] + print(f"count: {count}") + arcpy.management.CalculateField(layer, field_name, f"'{new_value}'", "PYTHON3") + arcpy.management.SelectLayerByAttribute(layer, "CLEAR_SELECTION") + + +add_field() +fix_values()