diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java index ec77d014fc036c2aa0df0d8f008b2f16f3fee647..3014c19e165b2656a46494c2afea9f1289dfba82 100755 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationController.java @@ -41,7 +41,6 @@ import no.nibio.vips.util.ServletUtil; import no.nibio.web.forms.*; import org.apache.commons.fileupload2.core.DiskFileItemFactory; import org.apache.commons.fileupload2.core.FileItem; -import org.apache.commons.fileupload2.core.FileUploadException; import org.apache.commons.fileupload2.jakarta.servlet6.JakartaServletFileUpload; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -85,6 +84,8 @@ public class ObservationController extends HttpServlet { throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); String action = request.getParameter("action"); + String returnTo = request.getParameter("returnTo"); + boolean returnToTimeSeries = returnTo != null && returnTo.equals("timeseries"); VipsLogicUser user = (VipsLogicUser) request.getSession().getAttribute("user"); // Get the organization groups for the current user List<OrganizationGroup> organizationGroups = null; @@ -254,18 +255,6 @@ public class ObservationController extends HttpServlet { observation.setCropOrganism( em.find(Organism.class, Integer.valueOf(request.getParameter("cropOrganismId")))); } - if (request.getParameter("observationTimeSeriesId") != null) { - ObservationTimeSeries observationTimeSeries = em.find(ObservationTimeSeries.class, - Integer.valueOf(request.getParameter("observationTimeSeriesId"))); - observation.setObservationTimeSeries(observationTimeSeries); - Calendar cal = Calendar.getInstance(); - cal.set(Calendar.YEAR, observationTimeSeries.getYear()); - cal.set(Calendar.MONTH, Calendar.getInstance().get(Calendar.MONTH)); - cal.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); - observation.setTimeOfObservation(cal.getTime()); - request.setAttribute("minTimeOfObservation", getMinDate(observationTimeSeries.getYear())); - request.setAttribute("maxTimeOfObservation", getMaxDate(observationTimeSeries.getYear())); - } List<Organism> allCrops; if (request.getParameter("organismId") != null) { @@ -277,14 +266,31 @@ public class ObservationController extends HttpServlet { allCrops = em.createNamedQuery("Organism.findAllCrops").getResultList(); } + request.setAttribute("observation", observation); + // Get the polygonServices List<PolygonService> polygonServices = observationBean.getPolygonServicesForOrganization(user.getOrganization_id()); - - request.setAttribute("observation", observation); request.setAttribute("polygonServices", polygonServices); - request.setAttribute("locationVisibilityFormValue", - ObservationController.LOCATION_VISIBILITY_FORM_VALUE_PUBLIC); + + if (request.getParameter("observationTimeSeriesId") != null) { + ObservationTimeSeries observationTimeSeries = em.find(ObservationTimeSeries.class, + Integer.valueOf(request.getParameter("observationTimeSeriesId"))); + observation.setObservationTimeSeries(observationTimeSeries); + Calendar cal = Calendar.getInstance(); + cal.set(Calendar.YEAR, observationTimeSeries.getYear()); + cal.set(Calendar.MONTH, Calendar.getInstance().get(Calendar.MONTH)); + cal.set(Calendar.DAY_OF_MONTH, Calendar.getInstance().get(Calendar.DAY_OF_MONTH)); + observation.setTimeOfObservation(cal.getTime()); + request.setAttribute("minTimeOfObservation", getMinDate(observationTimeSeries.getYear())); + request.setAttribute("maxTimeOfObservation", getMaxDate(observationTimeSeries.getYear())); + request.setAttribute("locationVisibilityFormValue", getLocationVisibilityFormValue( + observationTimeSeries.getPolygonService(), observationTimeSeries.getLocationIsPrivate())); + } else { + request.setAttribute("locationVisibilityFormValue", + ObservationController.LOCATION_VISIBILITY_FORM_VALUE_PUBLIC); + } + request.setAttribute("shortcut", request.getParameter("observationFormShortcutId") != null ? em.find(ObservationFormShortcut.class, Integer.valueOf(request.getParameter("observationFormShortcutId"))) @@ -312,6 +318,8 @@ public class ObservationController extends HttpServlet { request.setAttribute("observationMethods", em.createNamedQuery("ObservationMethod.findAll", ObservationMethod.class).getResultList()); request.setAttribute("organizationGroups", organizationGroups); + request.setAttribute("returnTo", returnTo); + request.setAttribute("returnPath", returnToTimeSeries ? "/observationTimeSeries?action=editObservationTimeSeriesForm&observationTimeSeriesId=" + observation.getObservationTimeSeriesId() : "/observation"); request.setAttribute("editAccess", "W"); // User always has edit access to new observation if (userBean.authorizeUser(user, VipsLogicRole.OBSERVATION_AUTHORITY, VipsLogicRole.ORGANIZATION_ADMINISTRATOR, VipsLogicRole.SUPERUSER)) { @@ -338,7 +346,7 @@ public class ObservationController extends HttpServlet { List<PolygonService> polygonServices = observationBean.getPolygonServicesForOrganization(user.getOrganization_id()); request.setAttribute("locationVisibilityFormValue", - this.getLocationVisibilityFormValue(observation)); + this.getLocationVisibilityFormValue(observation.getPolygonService(), observation.getLocationIsPrivate())); request.setAttribute("observation", observation); ObservationTimeSeries observationTimeSeries = observation.getObservationTimeSeries(); @@ -372,6 +380,8 @@ public class ObservationController extends HttpServlet { request.setAttribute("statusTypeIds", em.createNamedQuery("ObservationStatusType.findAll").getResultList()); } + request.setAttribute("returnTo", returnTo); + request.setAttribute("returnPath", returnToTimeSeries ? "/observationTimeSeries?action=editObservationTimeSeriesForm&observationTimeSeriesId=" + observation.getObservationTimeSeriesId() : "/observation"); if (request.getParameter("messageKey") != null) { request.setAttribute("messageKey", request.getParameter("messageKey")); } @@ -526,11 +536,12 @@ public class ObservationController extends HttpServlet { } // Redirect to form - response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://") - .append(ServletUtil.getServerName(request)) - .append("/observation?action=editObservationForm&observationId=") - .append(observation.getObservationId()) - .append("&messageKey=").append("observationStored").toString() + response.sendRedirect(Globals.PROTOCOL + "://" + + ServletUtil.getServerName(request) + + "/observation?action=editObservationForm&observationId=" + + observation.getObservationId() + + "&returnTo=" + returnTo + + "&messageKey=" + "observationStored" ); } else { @@ -562,13 +573,18 @@ public class ObservationController extends HttpServlet { VipsLogicRole.SUPERUSER)) { try { Integer observationId = Integer.valueOf(request.getParameter("observationId")); + Observation observation = observationId > 0 ? em.find(Observation.class, observationId) : new Observation(); + Integer observationTimeSeriesId = observation.getObservationTimeSeriesId(); + observationBean.deleteObservation(observationId); + String redirectTo = returnToTimeSeries ? "/observationTimeSeries?observationTimeSeries=" + observationTimeSeriesId + "&": "/observation?"; + // Redirect to list - response.sendRedirect(new StringBuilder(Globals.PROTOCOL + "://") - .append(ServletUtil.getServerName(request)) - .append("/observation") - .append("?messageKey=").append("observationDeleted").toString() + response.sendRedirect(Globals.PROTOCOL + "://" + + ServletUtil.getServerName(request) + + redirectTo + + "messageKey=observationDeleted" ); } catch (NullPointerException | NumberFormatException ex) { response.sendError(500, ExceptionUtil.getStackTrace(ex)); @@ -672,17 +688,17 @@ public class ObservationController extends HttpServlet { public static final String LOCATION_VISIBILITY_FORM_VALUE_PUBLIC = "public"; public static final String LOCATION_VISIBILITY_FORM_VALUE_MASK_PREFIX = "mask_"; - private String getLocationVisibilityFormValue(Observation observation) { + private String getLocationVisibilityFormValue(PolygonService polygonService, Boolean locationIsPrivate) { // Private is private, no matter what - if (observation.getLocationIsPrivate()) { + if (locationIsPrivate) { return ObservationController.LOCATION_VISIBILITY_FORM_VALUE_PRIVATE; } // Public can either be completely public or masked by a polygon layer // e.g. county borders - if (observation.getPolygonService() == null) { + if (polygonService == null) { return ObservationController.LOCATION_VISIBILITY_FORM_VALUE_PUBLIC; } - return ObservationController.LOCATION_VISIBILITY_FORM_VALUE_MASK_PREFIX + observation.getPolygonService() + return ObservationController.LOCATION_VISIBILITY_FORM_VALUE_MASK_PREFIX + polygonService .getPolygonServiceId(); } diff --git a/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationTimeSeriesController.java b/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationTimeSeriesController.java index bf6f5ef5767e4dccb026183025f0c39e5cfa55f7..1c2aca5f28c4983370a7c8763dae41f049c8c26e 100644 --- a/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationTimeSeriesController.java +++ b/src/main/java/no/nibio/vips/logic/controller/servlet/ObservationTimeSeriesController.java @@ -82,6 +82,7 @@ public class ObservationTimeSeriesController extends HttpServlet { response.setContentType("text/html;charset=UTF-8"); String action = request.getParameter("action"); VipsLogicUser user = (VipsLogicUser) request.getSession().getAttribute("user"); + request.setAttribute("messageKey", request.getParameter("messageKey")); List<ObservationTimeSeries> observationTimeSeriesList = observationTimeSeriesBean.getObservationTimeSeriesListForUser(user); if (request.getServletPath().endsWith("/observationTimeSeries")) { diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties index 8726f493b3cabd9abb2c749ecf04ec1309845a07..45e66ccb3c07cf67e8342a13a850d9c322e08ad1 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts.properties @@ -1090,6 +1090,7 @@ useWeatherStation=Use weather station multipleNewWarningMsg=This form is for adding the same forecast configuration to many weather stations simultaneously. timeSeriesList = Time series +addNewTimeSeries = Add new time series forTimeSeries=for time series newObservationTimeSeries=New observation time series editObservationTimeSeries=Edit observation time series @@ -1098,3 +1099,5 @@ observationTimeSeriesName=Name observationTimeSeriesDescription=Description year=Year observationTimeSeriesDeleted = Observation time series was deleted +observationTimeSeriesStored = Observation time series was stored + diff --git a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties index cbfd5821c9669b4d88e4d986430a0cf3fac31013..cbdfdd4bf6a61411ba36c9b35f33c00c610aa6d7 100755 --- a/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties +++ b/src/main/resources/no/nibio/vips/logic/i18n/vipslogictexts_nb.properties @@ -1089,6 +1089,7 @@ useWeatherStation=Bruk v\u00e6rstasjon multipleNewWarningMsg=Dette skjemaet er en snarvei for \u00e5 opprette likelydende varsel p\u00e5 flere v\u00e6rstasjoner. <a href="/forecastConfiguration?action=viewForecastConfiguration&forecastConfigurationId=-1">Klikk her</a> hvis du vil opprette bare ett varsel. timeSeriesList = Tidsserier +addNewTimeSeries = Legg til ny tidsserie forTimeSeries=for tidsserie newObservationTimeSeries=Ny tidsserie editObservationTimeSeries=Rediger tidsserie @@ -1097,3 +1098,5 @@ observationTimeSeriesName=Navn observationTimeSeriesDescription=Beskrivelse year=\u00c5r observationTimeSeriesDeleted = Tidsserie slettet +observationTimeSeriesStored = Tidsserie lagret + diff --git a/src/main/webapp/templates/observationForm.ftl b/src/main/webapp/templates/observationForm.ftl index 152b692ad18d49342d1b13bd768b1c8e1ef48435..f49681ee7e9a148dad735d6b57462dfc7646b69c 100755 --- a/src/main/webapp/templates/observationForm.ftl +++ b/src/main/webapp/templates/observationForm.ftl @@ -513,8 +513,8 @@ </#macro> <#macro page_contents> <div class="singleBlockContainer"> - <p><a href="/observation" class="btn btn-default back" - role="button">${i18nBundle.back}</a><#if observation.observationId?has_content><a + <p><a href="${returnPath}" class="btn btn-default back" role="button">${i18nBundle.back}</a> + <#if observation.observationId?has_content><a href="/observation?action=newObservationForm" class="btn btn-default" role="button">${i18nBundle.addNew}</a></#if></p> <h1><#if observation.observationId?has_content>${i18nBundle.editObservation}<#else>${i18nBundle.newObservation}</#if><#if observation.observationTimeSeriesId?has_content> ${i18nBundle.forTimeSeries}</#if><#if shortcut?has_content> - ${shortcut.getLocalLabel(currentLocale.language)?lower_case}</#if></h1> @@ -527,7 +527,7 @@ <div class="row"> <div class="col-md-6"> <#assign formId = "observationForm"> - <form id="${formId}" role="form" action="/observation?action=observationFormSubmit" + <form id="${formId}" role="form" action="/observation?action=observationFormSubmit&returnTo=${returnTo}" enctype="multipart/form-data" method="POST" onsubmit="return prepareFormSubmit(this);"> <!--form id="${formId}" role="form" action="/observation?action=observationFormSubmit" method="POST" onsubmit="this['geoInfo'].value=getFeatures();mw.save();console.log(this['observationData']);this['observationData'].value=JSON.stringify(mw.toInspect);return validateForm(this);"--> <!--form id="${formId}" role="form" action="/observation?action=observationFormSubmit" method="POST" onsubmit="this['geoInfo'].value=getFeatures();mw.save();console.log(this['observationData']);this['observationData'].value=JSON.stringify(mw.toInspect);validateForm(this);return false;"--> @@ -548,24 +548,27 @@ </div> </#if> <#if observation.observationTimeSeries?has_content> - <div class="form-group"> - <label>${i18nBundle.timeSeries}: ${observation.observationTimeSeries.name} (${observation.observationTimeSeries.year})</label><br> + <div class="alert alert-info"> <i>${i18nBundle.timeSeriesNonEditable}</i> </div> <div class="form-group"> - <label for="cropOrganismId">${i18nBundle.cropOrganismId}</label> + <label for="timeSeriesName">${i18nBundle.timeSeries}:</label> + <span id="timeSeriesName"><a href="/observationTimeSeries?action=editObservationTimeSeriesForm&observationTimeSeriesId=${observation.observationTimeSeries.observationTimeSeriesId}">${observation.observationTimeSeries.name} (${observation.observationTimeSeries.year})</a></span> + </div> + <div class="form-group"> + <label for="cropOrganismId">${i18nBundle.cropOrganismId}:</label> <span id="cropDisplayName"></span> </div> <div class="form-group"> - <label for="organismId">${i18nBundle.organism}</label> + <label for="organismId">${i18nBundle.organism}:</label> <span id="pestDisplayName"></span> </div> <div class="form-group"> - <label for="locationPointOfInterestId">${i18nBundle.location}</label> + <label for="locationPointOfInterestId">${i18nBundle.location}:</label> <span id="locationDisplayName"></span> </div> <div class="form-group"> - <label for="locationVisibility">Synlighet</label> + <label for="locationVisibility">Synlighet:</label> <span id="locationVisibility"> <#if locationVisibilityFormValue == 'public'> ${i18nBundle.locationIsPublic} @@ -804,7 +807,7 @@ <button type="submit" class="btn btn-default">${i18nBundle.submit}</button> <#if observation.observationId?has_content && editAccess == "W"> <button type="button" class="btn btn-danger" - onclick="if(confirm('${i18nBundle.confirmDelete}')){window.location.href='/observation?action=deleteObservation&observationId=${observation.observationId}';}">${i18nBundle.delete}</button> + onclick="if(confirm('${i18nBundle.confirmDelete}')){window.location.href='/observation?action=deleteObservation&observationId=${observation.observationId}&returnTo=${returnTo}';}">${i18nBundle.delete}</button> </#if> </form> </div> diff --git a/src/main/webapp/templates/observationTimeSeriesForm.ftl b/src/main/webapp/templates/observationTimeSeriesForm.ftl index b782178f678ba278ede656881d72407fa766038e..b1db7bc52e6eb1e8ba35dd251fc8e090417a21c5 100644 --- a/src/main/webapp/templates/observationTimeSeriesForm.ftl +++ b/src/main/webapp/templates/observationTimeSeriesForm.ftl @@ -50,7 +50,6 @@ } function refreshLocationPointOfInterests(selectedPointOfInterestId) { - console.log("Refresh POIs!", selectedPointOfInterestId) const poiTypes = { 0: "${i18nBundle.genericPlaces}", 2: "${i18nBundle.farms}", @@ -71,7 +70,9 @@ function buildPOIList(poiListElement, allPois, poiTypes, selectedPointOfInterestId) { poiListElement.options.length = 1; for (const [typeId, typeName] of Object.entries(poiTypes)) { - poiListElement.options[poiListElement.options.length] = new Option("-- " + typeName + " --", "-1"); + let poiTypeOption = new Option("-- " + typeName + " --", "-1"); + poiTypeOption.disabled = true; + poiListElement.options[poiListElement.options.length] = poiTypeOption; for (let i = 0; i < allPois.length; i++) { const poi = allPois[i]; @@ -351,9 +352,8 @@ <#macro page_contents> <div class="singleBlockContainer"> - <p><a href="/observationTimeSeries" class="btn btn-default back" role="button">${i18nBundle.back}</a><#if observationTimeSeries.observationTimeSeriesId?has_content><a href="/observation?action=newObservationForm&observationTimeSeriesId=${observationTimeSeries.observationTimeSeriesId}" class="btn btn-default" role="button">${i18nBundle.addNewObservationInTimeSeries}</a></#if></p> + <p><a href="/observationTimeSeries" class="btn btn-default back" role="button">${i18nBundle.back}</a><#if observationTimeSeries.observationTimeSeriesId?has_content><a href="/observation?action=newObservationForm&observationTimeSeriesId=${observationTimeSeries.observationTimeSeriesId}&returnTo=timeseries" class="btn btn-default" role="button">${i18nBundle.addNewObservationInTimeSeries}</a></#if></p> <h1><#if observationTimeSeries.observationTimeSeriesId?has_content>${i18nBundle.editObservationTimeSeries}<#else>${i18nBundle.newObservationTimeSeries}</#if><#if shortcut?has_content> - ${shortcut.getLocalLabel(currentLocale.language)?lower_case}</#if></h1> - <p><i>Kultur, organisme, år og sted kan ikke redigeres for tidsserier som inneholder observasjoner.</i></p> <div id="errorMsgEl" class="alert alert-danger" <#if !formValidation?has_content> style="display:none;"</#if>> <#if formValidation?has_content>${formValidation.validationMessages?replace("\n", "<br>")}</#if> </div> @@ -379,6 +379,9 @@ </div> </#if> <#if isEditable?has_content && !isEditable> + <div class="alert alert-info"> + <i>Kultur, organisme, år og sted kan ikke redigeres for tidsserier som inneholder observasjoner.</i> + </div> <div class="form-group"> <label for="cropDisplayName">${i18nBundle.cropOrganismId}</label> <span id="cropDisplayName"></span> @@ -472,7 +475,7 @@ onclick="addNewLocationPopup();">${i18nBundle.addNew}</button> </label> <select class="form-control" name="locationPointOfInterestId" id="locationPointOfInterestId" onchange="showCorrectMap();"> - <option value="-1">${i18nBundle.pleaseSelect} ${i18nBundle.location?lower_case}</option> + <option value="" disabled selected>${i18nBundle.pleaseSelect} ${i18nBundle.location?lower_case}</option> </select> <span class="help-block" id="${formId}_locationPointOfInterestId_validation"></span> </div> @@ -558,7 +561,7 @@ <td><#if observation.user?has_content>${observation.user.firstName!""} ${observation.user.lastName!""}</#if></td> <td>${observation.observationHeading}</td> <td><#switch observation.statusTypeId><#case 1>${i18nBundle.pending}<#break><#case 2>${i18nBundle.rejected}<#break><#case 3>${i18nBundle.approved}</#switch></td> - <td><#if user.isSuperUser() || user.isOrganizationAdmin() || userIsObservationAuthority || observation.userId == user.userId><a href="/observation?action=editObservationForm&observationId=${observation.observationId}" class="btn btn-default" role="button">${i18nBundle.edit}</a></#if></td> + <td><#if observation.userId == user.userId><a href="/observation?action=editObservationForm&observationId=${observation.observationId}&returnTo=timeseries" class="btn btn-default" role="button">${i18nBundle.edit}</a></#if></td> </tr> </#list> </tbody> diff --git a/src/main/webapp/templates/observationTimeSeriesList.ftl b/src/main/webapp/templates/observationTimeSeriesList.ftl index caaa4e255ad39939ad36a80a386309aedf18f28a..adcf2e25227c9be6a1f0ea57d450a1f2b8da058f 100644 --- a/src/main/webapp/templates/observationTimeSeriesList.ftl +++ b/src/main/webapp/templates/observationTimeSeriesList.ftl @@ -16,7 +16,7 @@ <#if messageKey?has_content> <div class="alert alert-success">${i18nBundle(messageKey)}</div> </#if> - <a href="/observationTimeSeries?action=newObservationTimeSeriesForm" class="btn btn-default" role="button">${i18nBundle.addNew}</a> + <a href="/observationTimeSeries?action=newObservationTimeSeriesForm" class="btn btn-default" role="button">${i18nBundle.addNewTimeSeries}</a> <div class="table-responsive"> <table class="table table-striped">