Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
223 commits
Select commit Hold shift + click to select a range
68ebbc3
page structure
erinz2020 Nov 26, 2025
c6ccd6a
selected match is a list
erinz2020 Nov 26, 2025
4d89a96
candidate matches
erinz2020 Nov 26, 2025
1e01e75
very basic MatchResult WIP
naknomum Dec 2, 2025
d2ec3e4
MatchResultProspect wip
naknomum Dec 2, 2025
a62f414
break down the main page
erinz2020 Dec 3, 2025
b830d70
zoom in, zoom out, pan
erinz2020 Dec 3, 2025
c970eb4
Merge branch 'match_result_page' of github.com:WildMeOrg/Wildbook int…
naknomum Dec 3, 2025
3c5df9d
convenience call to get json_result chunk of results
naknomum Dec 3, 2025
4190586
one log version; linting
naknomum Dec 3, 2025
6fad625
more MatchResult tinkering
naknomum Dec 3, 2025
6520566
why dont we have this yet?
naknomum Dec 4, 2025
f7763a5
scores and sorting and tasks oh my
naknomum Dec 4, 2025
290bffe
some recursion. sorta. some.
naknomum Dec 4, 2025
2a6b2b6
wip: api endpoint for tasks (only match-results now)
naknomum Dec 4, 2025
66950c4
new name
naknomum Dec 4, 2025
67cbe3d
api improvements
naknomum Dec 4, 2025
24fc57f
a little query annotation investigation
naknomum Dec 5, 2025
2a850cd
if a task has no MatchResults, we now generate them on the fly. or so…
naknomum Dec 5, 2025
c4b65ed
oops when we create on-the-fly, we have to commit the shepherd to per…
naknomum Dec 5, 2025
6eadf84
deal with candidate count
naknomum Dec 5, 2025
4fcd697
populate out the annotation data
naknomum Dec 5, 2025
9726c26
wip: getting inspection image
naknomum Dec 5, 2025
f21f423
fetch the image, make the asset
naknomum Dec 6, 2025
e5f29c2
baby steps to apply real json
erinz2020 Dec 8, 2025
138887b
allow creation from just json_result data too
naknomum Dec 8, 2025
a3764f7
if identification is complete, now we also (try to) make a MatchResult
naknomum Dec 8, 2025
d4ec6c1
add candidates table functions
erinz2020 Dec 9, 2025
fd8c092
get site settings from context to reduce repeating calls
erinz2020 Dec 9, 2025
2743ca8
cleaner functions to rocess data
erinz2020 Dec 9, 2025
920df64
filter data by projects, use processed columns from store
erinz2020 Dec 9, 2025
6d2da10
heatmask path fixes
naknomum Dec 10, 2025
35c23f4
add encounter/individual links, update default numResult value
erinz2020 Dec 10, 2025
d34fc28
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Dec 11, 2025
919ccd5
Merge branch 'main' into match_result_page
erinz2020 Dec 11, 2025
c65f8ab
functions to collect prospects
erinz2020 Dec 11, 2025
7bd6688
consider method as match result ready flag
erinz2020 Dec 11, 2025
b9950ca
update store, update ui
erinz2020 Dec 11, 2025
109b45a
unit tests of tasks/*/match-results GET api; tiny NPE bug fix
naknomum Dec 11, 2025
c5aad4d
unit tests for MatchResult
naknomum Dec 11, 2025
075d7ae
update page folder structure
erinz2020 Dec 12, 2025
3673fa1
move to sub folder
erinz2020 Dec 17, 2025
e11b9fa
move to sub folder
erinz2020 Dec 17, 2025
bb89bc5
add a reusable image and annotation overlay component
erinz2020 Dec 17, 2025
53b473c
add hover effect to inspect button, add atemporary workaround to dis…
erinz2020 Dec 17, 2025
8998ba3
experimenting something
erinz2020 Jan 6, 2026
5e24d10
Merge branch 'main' into match_result_page
erinz2020 Jan 6, 2026
9ce71ef
reduce calls of site-settings
erinz2020 Jan 6, 2026
333e847
remove unused variables
erinz2020 Jan 6, 2026
93fb114
case: single individual
erinz2020 Jan 7, 2026
f95e51a
case: confirm no match
erinz2020 Jan 8, 2026
bc01c1d
build out more info on projectsForUser in site-settings
naknomum Jan 8, 2026
a57368e
merge two individuals
erinz2020 Jan 8, 2026
e5fabb8
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Jan 8, 2026
01cbeb9
more cases
erinz2020 Jan 9, 2026
7c2719b
Merge branch 'main' into match_result_page
erinz2020 Jan 9, 2026
4473eb2
add projectIds (for filtering) into MatchResults
naknomum Jan 9, 2026
96f0510
Merge branch 'match_result_page' of github.com:WildMeOrg/Wildbook int…
naknomum Jan 9, 2026
c27c23d
add full screen loader, remove hatch mark button
erinz2020 Jan 9, 2026
36faada
group by task, not algorithm
erinz2020 Jan 12, 2026
8281130
handle hover, preview and click
erinz2020 Jan 12, 2026
e728ddd
add rowKey to selectedMatch
erinz2020 Jan 12, 2026
2c5ef30
show/hide/pan/zoom annotations
erinz2020 Jan 13, 2026
b09167b
update project options to get aligned on backend changes
erinz2020 Jan 13, 2026
a1a0725
i18n placeholders
erinz2020 Jan 13, 2026
eba13e4
filter by project
erinz2020 Jan 13, 2026
e4ebabe
add full screen mode
erinz2020 Jan 13, 2026
4c80651
add title to buttons
erinz2020 Jan 14, 2026
8cfc546
real logic to find if enc is in projs
naknomum Jan 14, 2026
19b3cca
hide inspection image button if there is no image
erinz2020 Jan 14, 2026
e258ccf
fix name:HotSpotter
naknomum Jan 14, 2026
de6e02c
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Jan 14, 2026
554b309
add inspector image modal
erinz2020 Jan 14, 2026
7cd2ca1
deal with empty results
erinz2020 Jan 14, 2026
9be83ee
do not show annotation while data is invalid
erinz2020 Jan 15, 2026
045c4fb
update icon names and styles
erinz2020 Jan 15, 2026
b18821d
i18n part1
erinz2020 Jan 15, 2026
beedc54
remove unused icons
erinz2020 Jan 15, 2026
918095c
add instruction modal
erinz2020 Jan 15, 2026
727bcb9
update table styles
erinz2020 Jan 15, 2026
4698f34
add criteria drawer placeholder
erinz2020 Jan 15, 2026
68bb742
add displayname and rotation info
erinz2020 Jan 15, 2026
bf84e73
handle image rotation info
erinz2020 Jan 21, 2026
fc45837
prep for vector-based results
naknomum Jan 21, 2026
77de84b
matchingset filter baby step 1
erinz2020 Jan 21, 2026
5c54596
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Jan 21, 2026
9eda192
Merge branch 'main' into match_result_page
erinz2020 Jan 21, 2026
da3d2f9
add 18n
erinz2020 Jan 21, 2026
432f171
update bottom bar
erinz2020 Jan 22, 2026
8ded839
handle empty filter
erinz2020 Jan 22, 2026
86769e9
i18n
erinz2020 Jan 22, 2026
e87465e
constructor for embed-based list of prospect annots
naknomum Jan 22, 2026
9dba2c3
put action bar on the top
erinz2020 Jan 23, 2026
8cbb1ff
add modals for confirm no match
erinz2020 Jan 23, 2026
72ecaf3
Merge branch 'match_result_page' of github.com:WildMeOrg/Wildbook int…
naknomum Jan 23, 2026
8074b5b
add confirm match modal
erinz2020 Jan 23, 2026
372e436
Merge branch 'match_result_page' of github.com:WildMeOrg/Wildbook int…
naknomum Jan 23, 2026
9f8e73a
UI polish and i18n
erinz2020 Jan 23, 2026
27c53b5
add encounter button
erinz2020 Jan 26, 2026
c448217
add an icon
erinz2020 Jan 26, 2026
ed4de7a
Merge branch 'main' into match_result_page
erinz2020 Jan 27, 2026
13eb15b
apparently we dont really need a shepherd here
naknomum Jan 28, 2026
cefa903
test for vector/annot based MatchResult() creation
naknomum Jan 28, 2026
125b909
a few UI updates
erinz2020 Jan 28, 2026
152ca8c
larger font size
erinz2020 Jan 28, 2026
57b92c6
guess we need a queryAnnotation
naknomum Jan 29, 2026
1760b17
update /iaResults.jsp to /react/match-results
erinz2020 Jan 29, 2026
76152a8
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Jan 29, 2026
ccc3fba
handle method info for vector stuff
naknomum Jan 29, 2026
80e3f69
Merge branch 'main' into match_result_page
erinz2020 Jan 29, 2026
7f54dde
i18n, update project dropdown, null handling
erinz2020 Jan 30, 2026
1cb7221
merge main
erinz2020 Feb 4, 2026
fb5df9a
update project filter to multiselect
erinz2020 Feb 4, 2026
0f7ad69
ui polish
erinz2020 Feb 4, 2026
6507fd9
(hopefully) bugfix to funky annotation assignment for MatchResults; l…
naknomum Feb 5, 2026
d7057a9
get next individual name from backend
erinz2020 Feb 5, 2026
9bd8b2b
minor changes
erinz2020 Feb 6, 2026
01911ad
update encounter icon, only display when on hover or selected
erinz2020 Feb 6, 2026
162237d
only display check mark when text box is on focus
erinz2020 Feb 6, 2026
a123652
add max width for score and individual name
erinz2020 Feb 6, 2026
f8b9109
when score is negative, show 0
erinz2020 Feb 9, 2026
d03665c
update zooming factor
erinz2020 Feb 10, 2026
3604708
ui polish
erinz2020 Feb 12, 2026
cb1fa45
add unit test cases
erinz2020 Feb 12, 2026
c30c34f
fix a bug
erinz2020 Feb 14, 2026
119143e
remove some unused variables
erinz2020 Feb 14, 2026
99454aa
indiv-style embedding MatchResult (beta)
naknomum Feb 18, 2026
d52acfa
combine annot/indiv; muchos debug; test fix
naknomum Feb 18, 2026
aa78e7a
merge main
erinz2020 Feb 18, 2026
3fc5aac
remove log
erinz2020 Feb 18, 2026
b781508
remove debug
naknomum Feb 18, 2026
ca62f12
Merge branch 'match_result_page' of github.com:WildMeOrg/Wildbook int…
naknomum Feb 18, 2026
81eb422
optimize store
erinz2020 Feb 19, 2026
b7a3262
guard null
erinz2020 Feb 19, 2026
daaf7aa
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Feb 19, 2026
f5f4755
use safe prospects
erinz2020 Feb 19, 2026
bf3c550
that ol math gotcha again
naknomum Feb 19, 2026
7718223
add minimum height
erinz2020 Feb 19, 2026
4f7843c
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Feb 19, 2026
28a898b
context is null
erinz2020 Feb 20, 2026
02ac42b
Merge branch 'main' into match_result_page
erinz2020 Feb 20, 2026
472e8c0
apply sitesettings provider part1
erinz2020 Feb 21, 2026
64baa0d
apply sitesettings provider part2: on footer
erinz2020 Feb 21, 2026
061361d
default context should not be {}
erinz2020 Feb 23, 2026
cf08c26
use sitesettings context provider instead of separate calls
erinz2020 Feb 23, 2026
14a698e
add id and testid
erinz2020 Feb 26, 2026
fcff049
i18n
erinz2020 Feb 27, 2026
8234020
add loading status to project select
erinz2020 Feb 27, 2026
0e6f98a
remove unnecessary dependency
erinz2020 Feb 27, 2026
d655e87
merge main
erinz2020 Feb 27, 2026
546750f
do task status and statusOverall on leaf node(s)
naknomum Mar 3, 2026
d2ac411
add status to indicate task is still running
erinz2020 Mar 4, 2026
fa04f77
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Mar 4, 2026
5f8b84b
i18n
erinz2020 Mar 4, 2026
cb77976
fix match criteria site-settings loading error
erinz2020 Mar 4, 2026
dde6a03
display algorithm description not name
erinz2020 Mar 4, 2026
47cf361
components should be observer to watch for site-settings loading status
erinz2020 Mar 4, 2026
8fadcbe
set task status to error when fails due to empty annots
naknomum Mar 5, 2026
25486c1
poll match results every 2 seconds is task is not completed or failed
erinz2020 Mar 5, 2026
5a042ac
polish i18n translations
erinz2020 Mar 5, 2026
d6688e1
throttle match-results polling to prevent request pileups on slow net…
erinz2020 Mar 5, 2026
c72ab09
debuggin was too noisy
naknomum Mar 6, 2026
fe2b0d6
display jobs with empty results
erinz2020 Mar 6, 2026
c92b512
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Mar 6, 2026
81b7000
show both completed and running tasks
erinz2020 Mar 9, 2026
2ccdbd2
show all running tasks
erinz2020 Mar 9, 2026
ca67392
Merge branch 'main' into match_result_page
erinz2020 Mar 9, 2026
ff037ea
get a safe query encounter, handle situation where first task is fail…
erinz2020 Mar 9, 2026
f1865ca
hide action bar when there is no encounter id
erinz2020 Mar 9, 2026
af08696
task.setModified()
naknomum Mar 9, 2026
fb95748
fix some parent/child persisty weirdness
naknomum Mar 9, 2026
a8a4177
failed tasks should be displayed
erinz2020 Mar 10, 2026
658431a
introducing task.statusDetails
naknomum Mar 10, 2026
d469e6f
UI polish
erinz2020 Mar 10, 2026
f23e517
show millis in a human readable way
naknomum Mar 10, 2026
1e1aaa7
some tinkering with task timeout
naknomum Mar 10, 2026
790e301
handle error code and translations
erinz2020 Mar 11, 2026
882f5ce
unsure how to treat null status, so going conservative on it
naknomum Mar 11, 2026
b1b55ad
log when MatchResult is created; set error when it fails
naknomum Mar 12, 2026
52e4524
update unit test cases
erinz2020 Mar 12, 2026
937e219
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Mar 12, 2026
85e8642
UI polish
erinz2020 Mar 12, 2026
35511e5
add svg icon
erinz2020 Mar 12, 2026
43c3471
we only try to generate a missing MatchResult on leaf tasks; no sense…
naknomum Mar 12, 2026
195f42c
add toast, update next individual name logic
erinz2020 Mar 12, 2026
830eefd
optimize store
erinz2020 Mar 13, 2026
e91bbcb
guard 0
erinz2020 Mar 13, 2026
a07d9a0
tiny tweak + log
naknomum Mar 13, 2026
1a0598b
preparing for a glorious future
naknomum Mar 13, 2026
e5261f5
UI polish
erinz2020 Mar 13, 2026
46b31d0
Merge branch 'match_result_page' of https://github.com/WildMeOrg/Wild…
erinz2020 Mar 13, 2026
3f14746
simplify alert message
erinz2020 Mar 16, 2026
5a40be4
fix broken test cases -- siteSettings
erinz2020 Mar 16, 2026
ad9cecf
fix broken test cases part 2
erinz2020 Mar 16, 2026
253e82a
deterministic ordering on prospects with identical scores
naknomum Mar 17, 2026
8d9755a
hide vector option in new match modal if there is no embedding
erinz2020 Mar 18, 2026
9cd1029
minor optimizations on some edge cases
erinz2020 Mar 20, 2026
de880db
project select: remove check mark, update tag render
erinz2020 Mar 24, 2026
fd07cbc
fix unbounded image dragging
erinz2020 Mar 24, 2026
56801c1
show encounter id on tooltip
erinz2020 Mar 24, 2026
b5ef93b
WIP pairx support on MatchResult
naknomum Apr 1, 2026
5efaee6
WIP pairx continued
naknomum Apr 1, 2026
a2feba7
pass arrays
naknomum Apr 1, 2026
898ec26
sometimes nice to use the correct url
naknomum Apr 1, 2026
6999c59
arrays of array(s)
naknomum Apr 1, 2026
e9fb74f
sigh
naknomum Apr 1, 2026
8ec2475
disable inspect icon when there is no inspect url
erinz2020 Apr 8, 2026
bef47eb
update inspection icon
erinz2020 Apr 10, 2026
bb918a2
Merge branch 'main' into match_result_page
erinz2020 Apr 16, 2026
f01d747
bug fixes
erinz2020 Apr 16, 2026
5a6d66a
Merge branch 'main' into match_result_page
erinz2020 Apr 16, 2026
d137354
create task.canUserAccess() then use this to determine access to task…
naknomum Apr 16, 2026
1bb9997
merge main
erinz2020 Apr 17, 2026
d15e41d
use Promise.allSettled for patch
erinz2020 Apr 17, 2026
8dfa6fd
use useMemo to reduce unnececcessary calling
erinz2020 Apr 17, 2026
a1f64cc
sort before compare incase properties in object are in different orders
erinz2020 Apr 17, 2026
710000a
fix i18n keys
erinz2020 Apr 17, 2026
36a6b96
remove console.error
erinz2020 Apr 17, 2026
c4100b9
frontend/src/components/AnnotationOverlay.jsx
erinz2020 Apr 17, 2026
3a91b90
remove unused page
erinz2020 Apr 17, 2026
97690a9
fix typo
erinz2020 Apr 17, 2026
665e958
roll back strict permissions on getting task match results
naknomum Apr 17, 2026
e14d910
merge main
erinz2020 Apr 18, 2026
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
Binary file added frontend/public/images/MatchResultExample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
57 changes: 34 additions & 23 deletions frontend/src/App.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useState, useRef } from "react";
import { IntlProvider } from "react-intl";
import messagesEn from "./locale/en.json";
import messagesEs from "./locale/es.json";
Expand All @@ -14,7 +14,9 @@ import LocaleContext from "./IntlProvider";
import FooterVisibilityContext from "./FooterVisibilityContext";
import Cookies from "js-cookie";
import FilterContext from "./FilterContextProvider";
import { SiteSettingsProvider } from "./SiteSettingsContext";
import { ToastContainer } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";

function App() {
const messageMap = {
Expand All @@ -24,16 +26,20 @@ function App() {
it: messagesIt,
de: messagesDe,
};

const initialLocale = Cookies.get("wildbookLangCode") || "en";
const [locale, setLocale] = useState(initialLocale);

const [visible, setVisible] = useState(true);

const containerStyle = {
display: "flex",
flexDirection: "column",
minHeight: "100vh",
};

const queryClient = new QueryClient();
const queryClientRef = useRef(null);
if (!queryClientRef.current) queryClientRef.current = new QueryClient();

const handleLocaleChange = (newLocale) => {
setLocale(newLocale);
Expand All @@ -59,7 +65,7 @@ function App() {
: "/";

return (
<QueryClientProvider client={queryClient}>
<QueryClientProvider client={queryClientRef.current}>
<LocaleContext.Provider
value={{ locale, onLocaleChange: handleLocaleChange }}
>
Expand All @@ -73,27 +79,32 @@ function App() {
defaultLocale="en"
messages={messageMap[locale]}
>
<FooterVisibilityContext.Provider value={{ visible, setVisible }}>
<FilterContext.Provider
value={{ filters, updateFilter, resetFilters }}
<SiteSettingsProvider>
<FooterVisibilityContext.Provider
value={{ visible, setVisible }}
>
<FrontDesk
adminUserInitialized={true}
setLocale={setLocale}
/>
<ToastContainer
position="top-right"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</FilterContext.Provider>
</FooterVisibilityContext.Provider>
<FilterContext.Provider
value={{ filters, updateFilter, resetFilters }}
>
<FrontDesk
adminUserInitialized={true}
setLocale={setLocale}
/>

<ToastContainer
position="top-right"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
</FilterContext.Provider>
</FooterVisibilityContext.Provider>
</SiteSettingsProvider>
</IntlProvider>
</BrowserRouter>
</div>
Expand Down
8 changes: 6 additions & 2 deletions frontend/src/AuthenticatedSwitch.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ const AboutUs = lazy(() => import("./pages/AboutUs"));

// Lazy load pages
const Login = lazy(() => import("./pages/Login"));
const Profile = lazy(() => import("./pages/Profile"));
const Home = lazy(() => import("./pages/Home"));
const EncounterSearch = lazy(
() => import("./pages/SearchPages/EncounterSearch"),
Expand All @@ -29,8 +28,12 @@ const EditAnnotation = lazy(() => import("./pages/EditAnnotation"));

const BulkImport = lazy(() => import("./pages/BulkImport/BulkImport"));
const BulkImportTask = lazy(() => import("./pages/BulkImport/BulkImportTask"));
const MatchResults = lazy(
() => import("./pages/MatchResultsPage/MatchResults"),
);

const Encounter = lazy(() => import("./pages/Encounter/Encounter"));
const Citation = lazy(() => import("./pages/Citation"));
const PoliciesAndData = lazy(
() => import("./pages/PoliciesAndData/PoliciesAndData"),
);
Expand Down Expand Up @@ -80,7 +83,8 @@ export default function AuthenticatedSwitch({
>
<Suspense fallback={<div>Loading...</div>}>
<Routes>
<Route path="/profile" element={<Profile />} />
<Route path="/match-results" element={<MatchResults />} />
<Route path="/citation" element={<Citation />} />
<Route path="/policies-and-data" element={<PoliciesAndData />} />
<Route
path="/how-to-photograph"
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/FrontDesk.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ import {
sessionWarningTime,
sessionCountdownTime,
} from "./constants/sessionWarning";
import useGetSiteSettings from "./models/useGetSiteSettings";
import useDocumentTitle from "./hooks/useDocumentTitle";
import { useSiteSettings } from "./SiteSettingsContext";

export default function FrontDesk() {
useDocumentTitle();
Expand All @@ -24,7 +24,7 @@ export default function FrontDesk() {
const [mergeData, setMergeData] = useState([]);
const [count, setCount] = useState(0);
const [loading, setLoading] = useState(true);
const { data, isLoading: siteSettingsLoading } = useGetSiteSettings();
const { data, isLoading: siteSettingsLoading } = useSiteSettings();
const showclassicsubmit = data?.showClassicSubmit;
const showClassicEncounterSearch = data?.showClassicEncounters;
const showHowToPhotograph = data?.showHowToPhotograph;
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/SiteSettingsContext.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React, { createContext, useContext } from "react";
import useGetSiteSettings from "./models/useGetSiteSettings";

const SiteSettingsContext = createContext(null);

export const SiteSettingsProvider = ({ children }) => {
const { data, isLoading, error } = useGetSiteSettings();
return (
<SiteSettingsContext.Provider value={{ data, isLoading, error }}>
{children}
</SiteSettingsContext.Provider>
);
};

export const useSiteSettings = () => {
const context = useContext(SiteSettingsContext);
if (context === null) {
throw new Error("useSiteSettings must be used within SiteSettingsProvider");
}
return context;
};
16 changes: 12 additions & 4 deletions frontend/src/__tests__/FrontDesk.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from "react";
import { render, screen, waitFor } from "@testing-library/react";
import axios from "axios";
import FrontDesk from "../FrontDesk";
import useGetSiteSettings from "../models/useGetSiteSettings";
import { useSiteSettings } from "../SiteSettingsContext";

jest.mock("../AuthenticatedSwitch", () => {
const MockComponent = () => <div>Authenticated</div>;
Expand Down Expand Up @@ -35,7 +35,7 @@ jest.mock("../components/SessionWarning", () => {
});

jest.mock("../hooks/useDocumentTitle", () => jest.fn());
jest.mock("../models/useGetSiteSettings");
jest.mock("../SiteSettingsContext", () => ({ useSiteSettings: jest.fn() }));
jest.mock("../models/notifications/getMergeNotifications", () => jest.fn());
jest.mock("../models/notifications/getCollaborationNotifications", () =>
jest.fn(),
Expand All @@ -46,7 +46,11 @@ jest.mock("axios");
describe("FrontDesk Component", () => {
beforeEach(() => {
jest.clearAllMocks();
useGetSiteSettings.mockReturnValue({ data: { showClassicSubmit: false } });
useSiteSettings.mockReturnValue({
data: { showClassicSubmit: false },
isLoading: false,
error: null,
});
});

test("renders UnauthenticatedSwitch if user is not logged in (401)", async () => {
Expand All @@ -65,7 +69,11 @@ describe("FrontDesk Component", () => {
test("keeps loading on non-401 login check failure (current behavior)", async () => {
const warnSpy = jest.spyOn(console, "warn").mockImplementation(() => {});
axios.head.mockRejectedValueOnce(new Error("Network Error"));
useGetSiteSettings.mockReturnValue({ data: {} });
useSiteSettings.mockReturnValue({
data: {},
isLoading: false,
error: null,
});

render(<FrontDesk />);

Expand Down
6 changes: 0 additions & 6 deletions frontend/src/__tests__/components/AuthenticatedSwitch.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,12 +80,6 @@ describe("AuthenticatedSwitch", () => {
expect(await screen.findByText("Home Page")).toBeInTheDocument();
});

test("renders the profile page when navigating to /profile", async () => {
window.history.pushState({}, "", "/profile");
renderComponent({ showAlert: false, setShowAlert: jest.fn() });
expect(await screen.findByText("Profile Page")).toBeInTheDocument();
});

test("renders the login page when navigating to /login", async () => {
window.history.pushState({}, "", "/login");
renderComponent({ showAlert: false, setShowAlert: jest.fn() });
Expand Down
28 changes: 22 additions & 6 deletions frontend/src/__tests__/components/Map.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import MapComponent from "../../components/Map";
import useGetSiteSettings from "../../models/useGetSiteSettings";
import { useSiteSettings } from "../../SiteSettingsContext";

jest.mock("../../models/useGetSiteSettings", () => jest.fn());
jest.mock("../../SiteSettingsContext", () => ({ useSiteSettings: jest.fn() }));

jest.mock("react-intl", () => {
const OriginalModule = jest.requireActual("react-intl");
Expand Down Expand Up @@ -31,22 +31,34 @@ describe("MapComponent", () => {
});

test("renders loading state when no googleMapsKey is present", () => {
useGetSiteSettings.mockReturnValue({ data: {} });
useSiteSettings.mockReturnValue({
data: {},
isLoading: false,
error: null,
});

render(<MapComponent setBounds={jest.fn()} />);

expect(screen.getByText(/MAP_IS_LOADING/i)).toBeInTheDocument();
});

test("renders the Draw button", () => {
useGetSiteSettings.mockReturnValue({ data: {} });
useSiteSettings.mockReturnValue({
data: {},
isLoading: false,
error: null,
});

render(<MapComponent setBounds={jest.fn()} />);
expect(screen.getByRole("button")).toBeInTheDocument();
});

test("toggles button text between DRAW and CANCEL", () => {
useGetSiteSettings.mockReturnValue({ data: {} });
useSiteSettings.mockReturnValue({
data: {},
isLoading: false,
error: null,
});

render(<MapComponent setBounds={jest.fn()} />);
const button = screen.getByRole("button");
Expand All @@ -63,7 +75,11 @@ describe("MapComponent", () => {
test("calls setBounds and setTempBounds when drawing is toggled", () => {
const setBoundsMock = jest.fn();
const setTempBoundsMock = jest.fn();
useGetSiteSettings.mockReturnValue({ data: {} });
useSiteSettings.mockReturnValue({
data: {},
isLoading: false,
error: null,
});

render(
<MapComponent
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React from "react";
import { screen, fireEvent } from "@testing-library/react";
import { DataTable } from "../../../pages/BulkImport/EditableDataTable";
import { renderWithProviders } from "../../../utils/utils";
import { useSiteSettings } from "../../../SiteSettingsContext";

const mockStore = {
spreadsheetData: [
Expand Down Expand Up @@ -42,7 +43,11 @@ const mockStore = {
]),
};

jest.mock("../../../models/useGetSiteSettings", () => () => ({
jest.mock("../../../SiteSettingsContext", () => ({
useSiteSettings: jest.fn(),
}));

useSiteSettings.mockReturnValue({
data: {
bulkImportMinimalFields: {},
locationData: { locationID: ["loc1", "loc2"] },
Expand All @@ -57,7 +62,9 @@ jest.mock("../../../models/useGetSiteSettings", () => () => ({
key1: ["val1", "val2"],
},
},
}));
isLoading: false,
error: null,
});

describe("EditableDataTable", () => {
test("renders the table with correct headers", () => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from "react";
import { render, fireEvent, act } from "@testing-library/react";
import "@testing-library/jest-dom";
import { useSiteSettings } from "../../../SiteSettingsContext";

jest.mock("../../../models/useGetSiteSettings", () => ({
jest.mock("../../../SiteSettingsContext", () => ({
__esModule: true,
default: () => ({ data: { maximumMediaSizeMegabytes: 5 } }),
useSiteSettings: jest.fn(),
}));
jest.mock("../../../pages/BulkImport/BulkImportImageUploadInfo", () => ({
__esModule: true,
Expand Down Expand Up @@ -52,6 +53,11 @@ describe("BulkImportImageUpload", () => {
};

beforeEach(() => {
useSiteSettings.mockReturnValue({
data: { maximumMediaSizeMegabytes: 5 },
isLoading: false,
error: null,
});
store = {
filesParsed: false,
imagePreview: [],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React from "react";
import { render, screen, fireEvent } from "@testing-library/react";
import BulkImportInstructionsModal from "../../../pages/BulkImport/BulkImportInstructionsModal";
import { useSiteSettings } from "../../../SiteSettingsContext";

jest.mock("../../../models/useGetSiteSettings", () => ({
jest.mock("../../../SiteSettingsContext", () => ({
__esModule: true,
default: () => ({ data: null }),
useSiteSettings: jest.fn(),
}));

jest.mock("react-intl", () => ({
Expand All @@ -22,6 +23,11 @@ describe("BulkImportInstructionsModal (without changing the component)", () => {
showInstructions: true,
setShowInstructions: jest.fn(),
};
useSiteSettings.mockReturnValue({
data: null,
isLoading: false,
error: null,
});
});

it("renders the Wildbook docs link in the NEED_HELP_DOCS step", () => {
Expand Down
Loading
Loading