From 2fc78e5a832c40f9f4dd69c730b67ebdc8e18d55 Mon Sep 17 00:00:00 2001 From: maisie-fisher Date: Sun, 8 Dec 2024 15:11:26 -0500 Subject: [PATCH 1/2] Adding ProjectList --- frontend/src/AuthenticatedSwitch.jsx | 2 + frontend/src/constants/navMenu.js | 2 +- frontend/src/css/projectList.css | 130 +++++++++++ frontend/src/locale/de.json | 13 +- frontend/src/locale/en.json | 11 +- frontend/src/locale/es.json | 11 +- frontend/src/locale/fr.json | 11 +- frontend/src/locale/it.json | 11 +- frontend/src/pages/ProjectList.jsx | 208 ++++++++++++++++++ src/main/webapp/header.jsp | 2 +- .../tablesorter/themes/pagination/next.jpg | Bin 0 -> 3077 bytes .../themes/pagination/previous.jpg | Bin 0 -> 2954 bytes 12 files changed, 393 insertions(+), 8 deletions(-) create mode 100644 frontend/src/css/projectList.css create mode 100644 frontend/src/pages/ProjectList.jsx create mode 100644 src/main/webapp/javascript/tablesorter/themes/pagination/next.jpg create mode 100644 src/main/webapp/javascript/tablesorter/themes/pagination/previous.jpg diff --git a/frontend/src/AuthenticatedSwitch.jsx b/frontend/src/AuthenticatedSwitch.jsx index 027c7958c7..eb864a797c 100644 --- a/frontend/src/AuthenticatedSwitch.jsx +++ b/frontend/src/AuthenticatedSwitch.jsx @@ -13,6 +13,7 @@ import Citation from "./pages/Citation"; import AdminLogs from "./pages/AdminLogs"; import ReportEncounter from "./pages/ReportsAndManagamentPages/ReportEncounter"; import ReportConfirm from "./pages/ReportsAndManagamentPages/ReportConfirm"; +import ProjectList from "./pages/ProjectList"; export default function AuthenticatedSwitch({ showAlert, @@ -58,6 +59,7 @@ export default function AuthenticatedSwitch({ } /> } /> + } /> } /> } /> } /> diff --git a/frontend/src/constants/navMenu.js b/frontend/src/constants/navMenu.js index 8c4613d371..062edf77c4 100644 --- a/frontend/src/constants/navMenu.js +++ b/frontend/src/constants/navMenu.js @@ -154,7 +154,7 @@ const authenticatedMenu = (username, showclassicsubmit) => [ defaultMessage="My Projects" /> ), - href: "/projects/projectList.jsp", + href: "/react/projects/overview", }, ], }, diff --git a/frontend/src/css/projectList.css b/frontend/src/css/projectList.css new file mode 100644 index 0000000000..64f8bf3df0 --- /dev/null +++ b/frontend/src/css/projectList.css @@ -0,0 +1,130 @@ +.projectListDiv { + margin-top: 20px; + margin-bottom: 40px; +} + +.headerContainer { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 10px; +} + +.newProject { + box-shadow: 3px 3px black; + background-color: #007DA3; + color: white; + padding: 8px 16px; /* Add padding for a nicer look */ + border: none; + border-radius: 4px; + cursor: pointer; +} + +table { + cursor: pointer; + border-spacing: 0; + width: 100%; + margin-bottom: 20px; +} + +table thead th { + background-color: white; + padding: 8px; + text-align: left; +} + +table tbody tr:nth-child(odd) { + background-color: #f2f2f3; +} + +table tbody tr:nth-child(even) { + background-color: white; +} + +table tbody td { + max-width: 350px; + word-wrap: break-word; + padding: 8px; +} + +table thead tr th { + background-image: url('../../../src/main/webapp/javascript/tablesorter/themes/blue/bg.gif'); + background-repeat: no-repeat; + background-position: center right; + padding-right: 30px; +} + +table thead tr .headerSortUp { + background-image: url('../../../src/main/webapp/javascript/tablesorter/themes/blue/asc.gif'); +} +table thead tr .headerSortDown { + background-image: url('../../../src/main/webapp/javascript/tablesorter/themes/blue/desc.gif'); +} + +.pagination { + display: flex; + justify-content: center; +} + +.pagination .itemCounter { + margin-right: 10px; + display: flex; + align-items: center; +} + +.pagination button { + cursor: pointer; + background-color: white; + background-repeat: no-repeat; + background-position: center; + background-size: 16px 16px; + outline: none; + border: 1px solid #DEE2E6; + color: #007DA3; + padding: 6px 8px; +} + +.pagination .previous-button { + background-image: url('../../../src/main/webapp/javascript/tablesorter/themes/pagination/previous.jpg'); +} + +.pagination .next-button { + background-image: url('../../../src/main/webapp/javascript/tablesorter/themes/pagination/next.jpg'); + margin-right: 10px; +} + +.pagination-options { + align-items: center; + margin-right: 10px; +} + +.pagination-options select { + background-color: white; + border: 1px solid #ddd; + outline: none; + cursor: pointer; + padding: 8px 8px; + -webkit-appearance: none; + appearance: none; +} + +.goto-box { + display: flex; + align-items: center; +} + +.goto-box input { + margin-left: 10px; + width: 30px; + border: 1px solid #ddd; + text-align: center; + outline: none; + padding: 6px; +} + +.pagination button.active { + background-color: #007DA3; + color: white; + font-weight: bold; + border: 1px solid #007DA3; +} \ No newline at end of file diff --git a/frontend/src/locale/de.json b/frontend/src/locale/de.json index 2bd943d364..a88f236384 100644 --- a/frontend/src/locale/de.json +++ b/frontend/src/locale/de.json @@ -317,5 +317,14 @@ "BEERROR_REQUIRED" : "Konnte nicht übermittelt werden; erforderliches Feld fehlt: ", "BEERROR_INVALID" : "Konnte nicht übermittelt werden; Feldformat war ungültig: ", "BEERROR_UNKNOWN" : "Konnte aufgrund eines unbekannten Fehlers nicht abgeschickt werden.", - "ANON_UPLOAD_IMAGE_WARNING": "Bilder können erst hochgeladen werden, wenn das Captcha abgeschlossen ist." -} \ No newline at end of file + "ANON_UPLOAD_IMAGE_WARNING": "Bilder können erst hochgeladen werden, wenn das Captcha abgeschlossen ist.", + "PROJECTS_FOR" : "Projekte für", + "NEW_PROJECT" : "Neues Projekt", + "PROJECTS_ID" : "Projekte ID", + "PERCENTAGE_IDENTIFIED" : "Prozentsatz identifiziert", + "TOTAL" : "Gesamt", + "ITEMS" : "Artikel", + "INPUT_PAGE_ALERT" : "Bitte geben Sie eine gültige Seitenzahl zwischen 1 und {totalPages}.", + "NO_PROJECTS" : "Keine Projekte", + "PROJECT_LIST_TITLE": "Wildbook – Meine Projekte" +} diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json index 663a65a2f0..8278c718e7 100644 --- a/frontend/src/locale/en.json +++ b/frontend/src/locale/en.json @@ -317,5 +317,14 @@ "BEERROR_REQUIRED" : "Could not submit; missing required field: ", "BEERROR_INVALID" : "Could not submit; field format was invalid: ", "BEERROR_UNKNOWN" : "Could not submit due to unknown error.", - "ANON_UPLOAD_IMAGE_WARNING": "Images cannot be uploaded until captcha is complete." + "ANON_UPLOAD_IMAGE_WARNING": "Images cannot be uploaded until captcha is complete.", + "PROJECTS_FOR" : "Projects for", + "NEW_PROJECT" : "New Project", + "PROJECTS_ID" : "Projects ID", + "PERCENTAGE_IDENTIFIED" : "Percentage Identified", + "TOTAL" : "Total", + "ITEMS" : "items", + "INPUT_PAGE_ALERT" : "Please enter a valid page number between 1 and {totalPages}.", + "NO_PROJECTS" : "No Projects", + "PROJECT_LIST_TITLE": "Wildbook - My Projects" } \ No newline at end of file diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json index ab6f09e7ab..a6685a690f 100644 --- a/frontend/src/locale/es.json +++ b/frontend/src/locale/es.json @@ -316,5 +316,14 @@ "BEERROR_REQUIRED" : "No se ha podido enviar; falta el campo obligatorio: ", "BEERROR_INVALID" : "No se pudo enviar; el formato del campo no era válido: ", "BEERROR_UNKNOWN" : "No se pudo enviar debido a un error desconocido.", - "ANON_UPLOAD_IMAGE_WARNING": "No se pueden subir imágenes hasta que se complete el captcha." + "ANON_UPLOAD_IMAGE_WARNING": "No se pueden subir imágenes hasta que se complete el captcha.", + "PROJECTS_FOR" : "Proyectos para", + "NEW_PROJECT" : "Nuevo Proyecto", + "PROJECTS_ID" : "Identificación de proyectos", + "PERCENTAGE_IDENTIFIED" : "Porcentaje identificado", + "TOTAL" : "Total", + "ITEMS" : "elementos", + "INPUT_PAGE_ALERT" : "Por favor, introduzca un número de página válido entre 1 y {totalPages}.", + "NO_PROJECTS" : "Sin proyectos", + "PROJECT_LIST_TITLE": "Wildbook - Mis Proyectos" } \ No newline at end of file diff --git a/frontend/src/locale/fr.json b/frontend/src/locale/fr.json index 6aadc9ff1a..4f3b72ff64 100644 --- a/frontend/src/locale/fr.json +++ b/frontend/src/locale/fr.json @@ -316,5 +316,14 @@ "BEERROR_REQUIRED" : "Impossible de soumettre ; champ requis manquant : ", "BEERROR_INVALID" : "Impossible de soumettre ; le format du champ n'est pas valide : ", "BEERROR_UNKNOWN" : "Impossible de soumettre en raison d'une erreur inconnue.", - "ANON_UPLOAD_IMAGE_WARNING": "Les images ne peuvent pas être téléchargées tant que le captcha n'est pas complété." + "ANON_UPLOAD_IMAGE_WARNING": "Les images ne peuvent pas être téléchargées tant que le captcha n'est pas complété.", + "PROJECTS_FOR" : "Projets pour", + "NEW_PROJECT" : "Nouveau projet", + "PROJECTS_ID" : "ID de projets", + "PERCENTAGE_IDENTIFIED" : "Pourcentage identifié", + "TOTAL" : "Total", + "ITEMS" : "articles", + "INPUT_PAGE_ALERT" : "Veuillez saisir un numéro de page valide entre 1 et {totalPages}.", + "NO_PROJECTS" : "Aucun projet", + "PROJECT_LIST_TITLE": "Wildbook - Mes projets" } \ No newline at end of file diff --git a/frontend/src/locale/it.json b/frontend/src/locale/it.json index f0dc73ac18..3cbfa33cd8 100644 --- a/frontend/src/locale/it.json +++ b/frontend/src/locale/it.json @@ -316,5 +316,14 @@ "BEERROR_REQUIRED" : "Impossibile inviare; manca un campo obbligatorio: ", "BEERROR_INVALID" : "Impossibile inviare; il formato del campo non era valido: ", "BEERROR_UNKNOWN" : "Impossibile inviare a causa di un errore sconosciuto.", - "ANON_UPLOAD_IMAGE_WARNING": "Non è possibile caricare immagini finché il captcha non è completato." + "ANON_UPLOAD_IMAGE_WARNING": "Non è possibile caricare immagini finché il captcha non è completato.", + "PROJECTS_FOR" : "Progetti per", + "NEW_PROJECT" : "Nuovo progetto", + "PROJECTS_ID" : "ID progetti", + "PERCENTAGE_IDENTIFIED" : "Percentuale identificata", + "TOTAL" : "Totale", + "ITEMS" : "elementi", + "INPUT_PAGE_ALERT" : "Inserisci un numero di pagina valido compreso tra 1 e {totalPages}.", + "NO_PROJECTS" : "Nessun progetto", + "PROJECT_LIST_TITLE": "Wildbook - I miei progetti" } \ No newline at end of file diff --git a/frontend/src/pages/ProjectList.jsx b/frontend/src/pages/ProjectList.jsx new file mode 100644 index 0000000000..dd8e81519b --- /dev/null +++ b/frontend/src/pages/ProjectList.jsx @@ -0,0 +1,208 @@ +import React, { useState, useEffect } from "react"; +import "../css/projectList.css"; +import axios from "axios"; +import { FormattedMessage } from "react-intl"; +import { useIntl } from "react-intl"; + +export default function ProjectList() { + const intl = useIntl(); + const [currentUser, setCurrentUser] = useState(null); + const [projects, setProjects] = useState([]); + const [sortConfig, setSortConfig] = useState({ key: null, direction: "asc" }); + const [currentPage, setCurrentPage] = useState(1); + const [projectsPerPage, setProjectsPerPage] = useState(10); + const [gotoPage, setGotoPage] = useState(1); + + const fetchData = async () => { + const response = await axios.get("/api/v3/user"); + setCurrentUser(response.data.displayName); + const projectsResponse = await axios.get("/api/v3/projects"); + setProjects(projectsResponse.data.projects); + }; + + useEffect(() => { + document.title = intl.formatMessage({ id: "PROJECT_LIST_TITLE" }); + fetchData(); + }, []); + + const sortProjects = (key) => { + let direction = "asc"; + if (sortConfig.key === key && sortConfig.direction === "asc") { + direction = "desc"; + } + setSortConfig({ key, direction }); + + const sortedProjects = [...projects].sort((a, b) => { + if (a[key] < b[key]) { + return direction === "asc" ? -1 : 1; + } + if (a[key] > b[key]) { + return direction === "asc" ? 1 : -1; + } + return 0; + }); + setProjects(sortedProjects); + }; + + // Determines if table headers have up or down arrow: + const getHeaderClass = (key) => { + if (sortConfig.key !== key) return ""; + return sortConfig.direction === "asc" ? "headerSortUp" : "headerSortDown"; + }; + + const totalPages = Math.ceil(projects.length / projectsPerPage); + + const paginatedProjects = projects.slice( + (currentPage - 1) * projectsPerPage, + currentPage * projectsPerPage, + ); + + const handlePageChange = (page) => { + if (page < 1 || page > totalPages) { + alert(intl.formatMessage({ id: "INPUT_PAGE_ALERT" }, { totalPages })); + return; + } + setCurrentPage(page); + }; + + return ( +
+
+

+ {currentUser} +

+ +
+ {projects.length === 0 ? ( +

+ +

+ ) : ( + + + + + + + + + + + {paginatedProjects.map((project) => ( + + (window.location.href = `/projects/project.jsp?id=${project.id}`) + } + > + + + + + + ))} + +
sortProjects("name")} + className={getHeaderClass("name")} + > + + sortProjects("id")} + className={getHeaderClass("id")} + > + + sortProjects("percentComplete")} + className={getHeaderClass("percentComplete")} + > + + sortProjects("numberEncounters")} + className={getHeaderClass("numberEncounters")} + > + +
{project.name}{project.id}{project.percentComplete}%{project.numberEncounters}
+ )} +
+
+ {projects.length}{" "} + +
+ + {Array.from({ length: totalPages }, (_, index) => ( + + ))} + +
+ + +
+
+ + { + const value = e.target.value; + // Only Numeric Input + if (!value || /^[0-9]+$/.test(value)) { + setGotoPage(Number(value)); + } + }} + onKeyDown={(e) => { + if (e.key === "Enter") { + handlePageChange(gotoPage); + } + }} + /> +
+
+
+ ); +} diff --git a/src/main/webapp/header.jsp b/src/main/webapp/header.jsp index 0ccad495e4..8923af297e 100755 --- a/src/main/webapp/header.jsp +++ b/src/main/webapp/header.jsp @@ -481,7 +481,7 @@ if(request.getUserPrincipal()!=null){
  • <%=props.getProperty("myIndividuals")%>
  • <%=props.getProperty("mySightings")%>
  • <%=props.getProperty("myBulkImports")%>
  • -
  • <%=props.getProperty("myProjects")%>
  • +
  • <%=props.getProperty("myProjects")%>
  • diff --git a/src/main/webapp/javascript/tablesorter/themes/pagination/next.jpg b/src/main/webapp/javascript/tablesorter/themes/pagination/next.jpg new file mode 100644 index 0000000000000000000000000000000000000000..532cda6168ac7a0873d600baff2e91d2768fc4ce GIT binary patch literal 3077 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 SBmU33$lzbB4gJO1^M3)+GBo-C literal 0 HcmV?d00001 diff --git a/src/main/webapp/javascript/tablesorter/themes/pagination/previous.jpg b/src/main/webapp/javascript/tablesorter/themes/pagination/previous.jpg new file mode 100644 index 0000000000000000000000000000000000000000..cc71adcbdd3ea3e7d4189f229a6e521312cada0e GIT binary patch literal 2954 zcmbu9do9?KTbAEsPe!uhE=bX=Z{`frSIp_6$p7$eqBANqs zx}scA07wD^+6&qX0HSHY5di(e_}t_lwg7=dod8r8I0_t<1VI4_C`b|t67>KG002q- z*&Fy0APGsZl(dYjocuO%LDNn^0wgIZ0hW}K0)xfXm&N}87%H_()9k3U;;}H9eORS~ zskxQ1S`PJH%3hCo+J{cYrOC;wz*N=L_v`5D=^L0^SXx=z*gAgggmV7I#ns!#*UvxT zc;Kni;SrcKkx}spxbqkA7cX5+ClE>3GBWe>3kr*_-zYBmnNmf)MY~O}{-vR@skx=~ z9+orUP9EL^6LigckZfC6v(UEZOC(&RPGe$>ykJlS zI0b07@ky*#CYZcW^WDtsp`mkLZ-X`t1T{{WtJbaJ*koG#`(#btEyb&?*Ol|<8q|*y z)f`kaUEJN2(`d&BSTZ;CdcDa8rCx<|A|TNr;Vd)ZL})mIjfC>yW_;%>zX)}Q&s0FgnB-iz8I)t|px@^4noiZwOh?bLHO%E&BKd9&jmlP z%s4T5G=fQCZthQfg=^mldxgWJN$wj~gmx9KH4D0Z)`}2p1qrJb0hh{xXKHK$1HLye zq;5CTF2&+o8&{|#*3fjK>y4O&iYj|HLW)C_uY<&n2iqOa!9Gc>S~ujhVjv+f+KmXM zS#yI3WzGHG#zRp$C9!?;VXGctjtD`QSbed$Y2o-5JcUl= zZ14SO`#lJ{WJVUHeuGrZ6^10TBOg3Uws!T9{R zf}7FJk5=Jw>D_attw}1|6ddKQc6(BZ-JIC5N=F4EYa~7Laiv4Hbzhl*Ila%6hK6Qo z%HHnP&NE-u`ss^pPiHJ@-CA;gInZu7^{N$m4_;P#Z?JiXtaQow$d_;4VXBiEcT1R2 zZ%TP&BSWZRbV3f0Fu9@tmGt_Hhta+D^y@`5bP zF5bh-#lC&t34Sn*@8yPP*LVe#+`~Y9+3Qyu7j`?opq7keEsyxTW+@Z8MSzDr@7s=P z@doL>&FAI2@g@l3L2+okImGfk><@LYB#p=OB=qAC&k<ai&FUFv-+K;a9ODFvn zb@uzN5br|gGxPhXA%#_pW0hNCM{Wa)+76-4bM z?jax6`nhH}Z*YVrZ{|fW@+mOIlg|vvW%MPN`7b)Z>k_;Bi^*eWcL~+;iu15kq&x2s z7eh>Vq>6|4sh^&5zLs=^(H-8{)>y!xP$SipMTd3!!y1qcivBX>u5sVHf=rXq^oeZqcWT|(bIOtKu4RF7g|@i``}I1s>>k7= z>kjbOrBkl37B8YOq#`&xt*5_4T+-lfKK9CwYN6hm-ShoYKp-uId@pFwUcP@7@ zUE5V-u!mhh@v9hXxC3h{h}1WVP=IWO3OhTRZVIOm4Hwddhi34GfjrA!ksp)ce7lOv zw2&!5iWgrey@+>KefG+#VH+!mcX{+-krJ!{qeNq~$ zb3lh^Nw!TtwH>WeW#AByiH}K_mTkHHU8=K4cs3?~yQX zjW+J4+VuIn9xb4crB~`Zt=p_PP Date: Thu, 12 Dec 2024 11:44:42 -0500 Subject: [PATCH 2/2] Updated link in servletResponseTemplate.htm --- src/main/resources/servletResponseTemplate.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/servletResponseTemplate.htm b/src/main/resources/servletResponseTemplate.htm index 1c4a6f9cab..cf53b85680 100755 --- a/src/main/resources/servletResponseTemplate.htm +++ b/src/main/resources/servletResponseTemplate.htm @@ -110,7 +110,7 @@
  • My Individuals
  • My Sightings
  • My BulkImports
  • -
  • My Projects
  • +
  • My Projects