diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/OnePagerApp.java b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/OnePagerApp.java index 551aa6d1370..903bff8ed32 100644 --- a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/OnePagerApp.java +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/OnePagerApp.java @@ -41,7 +41,7 @@ * @author mihai */ public class OnePagerApp extends AuthenticatedWebApplication { - + public static boolean IS_DEVELOPMENT_MODE = false; private static Logger logger = Logger.getLogger(OnePagerApp.class); @@ -73,25 +73,26 @@ public void init() { IS_DEVELOPMENT_MODE = true; } + //getResourceSettings().setStripJavaScriptCommentsAndWhitespace(true); //getResourceSettings().setAddLastModifiedTimeToResourceReferenceUrl(true); //TODO: //TODO:1.5 //TODO: /* - * - if (true) { + * + if (true) { ResourceMount.mountWicketResources("script", this); ResourceMount mount = new ResourceMount(); //.setResourceVersionProvider(new RevisionVersionProvider()); - - + + LinkedList csslist = new LinkedList(); //csslist.add(new ResourceSpec(YuiLib.class, "calendar/assets/skins/sam/calendar.css")); //csslist.add(new ResourceSpec(new ResourceReference("TEMPLATE/ampTemplate/css_2/amp-wicket.css"))); - - + + LinkedList jslist = new LinkedList(); jslist.add(new ResourceSpec(JQueryBehavior.class, JQueryBehavior.JQUERY_FILE_NAME)); //jslist.add(new ResourceSpec(AutoCompleteBehavior.class, "wicket-autocomplete.js")); @@ -99,8 +100,8 @@ public void init() { jslist.add(new ResourceSpec(IHeaderContributor.class, "wicket-event.js")); jslist.add(new ResourceSpec(AmpSubsectionFeaturePanel.class, "subsectionSlideToggle.js")); jslist.add(new ResourceSpec(AmpStructuresFormSectionFeature.class, "gisPopup.js")); -// jslist.add(new ResourceSpec(YuiLib.class, "yahoo/yahoo-min.js")); -// jslist.add(new ResourceSpec(YuiLib.class, "yahoodomevent/yahoo-dom-event.js")); +// jslist.add(new ResourceSpec(YuiLib.class, "yahoo/yahoo-min.js")); +// jslist.add(new ResourceSpec(YuiLib.class, "yahoodomevent/yahoo-dom-event.js")); // jslist.add(new ResourceSpec(YuiLib.class, "yuiloader.js")); //can't use the min version, because the normal one will be included too // jslist.add(new ResourceSpec(YuiLib.class, "calendar/calendar-min.js")); // jslist.add(new ResourceSpec(DatePicker.class, "wicket-date.js")); @@ -108,12 +109,12 @@ public void init() { jslist.add(new ResourceSpec(AmpAjaxBehavior.class, "translationsOnDocumentReady.js")); jslist.add(new ResourceSpec(AmpActivityFormFeature.class, "previewLogframe.js")); jslist.add(new ResourceSpec(AmpActivityFormFeature.class, "saveNavigationPanel.js")); - + mount.clone() .setPath("/style/all-23.css") .addResourceSpecs(csslist) .mount(this); - + mount.clone() .setPath("/style/all-2.js") .addResourceSpecs(jslist) @@ -219,16 +220,17 @@ public void setAuthenticationManager(AuthenticationManager authenticationManager @Override protected WebResponse newWebResponse(WebRequest webRequest, HttpServletResponse httpServletResponse) { return new ServletWebResponse((ServletWebRequest) webRequest, httpServletResponse) { + @Override public void flush() { + // Add the X-Frame-Options header try { getContainerResponse().flushBuffer(); } catch (SocketException e) { logger.warn("Socket exception encountered, ignoring", e); } catch (IOException e) { - // Socket Exception can be wrapped by a container specific exception. - // So we check the cause of the container exception - Throwable rootCause = null != e.getCause() ? e.getCause() : e; + // Check if the root cause is a SocketException + Throwable rootCause = (e.getCause() != null) ? e.getCause() : e; if (rootCause instanceof SocketException) { logger.warn("Socket exception encountered, ignoring.", rootCause); return; diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/XFrameOptionsFilter.java b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/XFrameOptionsFilter.java new file mode 100644 index 00000000000..8f4463db1f4 --- /dev/null +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/XFrameOptionsFilter.java @@ -0,0 +1,31 @@ +package org.dgfoundation.amp.onepager; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class XFrameOptionsFilter implements Filter { + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // Initialization code if needed + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) + throws IOException, ServletException { + HttpServletResponse httpResponse = (HttpServletResponse) response; + httpResponse.setHeader("Access-Control-Allow-Origin", "*"); + httpResponse.setHeader("X-Frame-Options", "SAMEORIGIN"); + chain.doFilter(request, response); + } + + @Override + public void destroy() { + // Cleanup code if needed + } +} diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/AmpActivityFormFeature.java b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/AmpActivityFormFeature.java index a8d4a74a264..fb2e50a7600 100644 --- a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/AmpActivityFormFeature.java +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/AmpActivityFormFeature.java @@ -33,6 +33,7 @@ import org.apache.wicket.model.Model; import org.apache.wicket.model.PropertyModel; import org.apache.wicket.request.flow.RedirectToUrlException; +import org.apache.wicket.request.http.WebResponse; import org.apache.wicket.request.mapper.parameter.PageParameters; import org.apache.wicket.request.resource.PackageResourceReference; import org.apache.wicket.util.time.Duration; @@ -94,7 +95,7 @@ * @since Jun 7, 2011 */ public class AmpActivityFormFeature extends AmpFeaturePanel { - + private static final long serialVersionUID = 1L; protected Form activityForm; private static final Integer GO_TO_DESKTOP=1; @@ -116,13 +117,13 @@ public ListView getFeatureList() { TranslatorUtil.getTranslatedText("The sum of disbursements is greater than the sum of commitments"); private static final String EXPENDITURES_BIGGER_ERROR = TranslatorUtil.getTranslatedText("The sum of expenditures is greater than the sum of disbursements"); - + /** - * Toggles the validation of semantic validators. + * Toggles the validation of semantic validators. * @param enabled whether these validators are enabled * @param form the form to set the validators - * @param target + * @param target * @see AmpSemanticValidatorField * @see AmpSemanticValidator */ @@ -143,7 +144,7 @@ public void component(AmpPercentageTextField ifs, //target.add(ifs); } }); - + // visit all the semantic validator fields and enable/disable them form.visitChildren(AmpSemanticValidatorField.class, new IVisitor, Void>() { @@ -167,8 +168,8 @@ public void component(AmpSemanticValidatorField ifs, public void component( AmpIdentificationFormSectionFeature ifs, IVisit visit) { - toggleFormComponent (enabled,target,ifs,visit); - toggleFormRichTextComponent(enabled,target, ifs,visit); + toggleFormComponent (enabled,target,ifs,visit); + toggleFormRichTextComponent(enabled,target, ifs,visit); } }); @@ -200,16 +201,16 @@ public void component( IVisit visit) { /* Validator for date will make the date field mandatory only when there is an amount entered * in proposed project code field AMP-17234 - * Review to make is more readable + * Review to make is more readable */ AmpDatePickerFieldPanel proposedDate= null; - + //if it is saving as draft, disable required validator for proposed date if (!enabled) { proposedDate = (AmpDatePickerFieldPanel) component.get("funDate"); } //if proposed amount is not entered then, disable required validator for proposed Date - else if(component.getParent().getParent().getId().equalsIgnoreCase("funDate") && + else if(component.getParent().getParent().getId().equalsIgnoreCase("funDate") && component.getParent().getParent().getParent().get("amount").getDefaultModel().getObject()==null){ proposedDate = (AmpDatePickerFieldPanel)component.getParent().getParent(); } @@ -218,11 +219,11 @@ else if(component.getParent().getParent().getId().equalsIgnoreCase("funDate") && String js = String.format("$('#%s').change();",proposedDate.getDate().getMarkupId()); target.appendJavaScript(js); } - + } }); - - + + } private void toggleFormComponent( @@ -244,7 +245,7 @@ private void toggleFormComponent (boolean enabled, final AjaxRequestTarget targe AmpRequiredComponentContainer ifs, IVisit visit) { toggleFormComponent(enabled, target, ifs, visit, true); } - + private void toggleFormComponent (boolean enabled, final AjaxRequestTarget target, AmpRequiredComponentContainer ifs, IVisit visit, boolean stopVisit) { List > requiredComponents = ifs.getRequiredFormComponents(); @@ -267,41 +268,41 @@ private void toggleFormComponent (boolean enabled, final AjaxRequestTarget targe * @param id * @param am * @param fmName - * @param newActivity - * @param listModel + * @param newActivity + * @param listModel * @throws Exception */ public AmpActivityFormFeature(String id, final IModel am, String fmName, final boolean newActivity, AbstractReadOnlyModel> listModel) throws Exception { super(id, am, fmName, true); - + this.enabledFmButton.setVisible(false); this.visibleFmButton.setVisible(false); this.ignoreFmVisibility = true; this.ignoreFmButtonsVisibility = true; this.setVisible(true); - - activityForm=new Form("activityForm") { + + activityForm=new Form("activityForm") { @Override protected void onError() { super.onError(); } }; activityForm.setOutputMarkupId(true); - + String actNameStr = am.getObject().getName(); if (actNameStr != null && !actNameStr.trim().isEmpty()) { actNameStr = "(" + actNameStr + ")"; } Label activityName = new Label("activityName", actNameStr); add(activityName); - + final FeedbackPanel feedbackPanel = new FeedbackPanel("feedbackPanel"); feedbackPanel.setOutputMarkupPlaceholderTag(true); feedbackPanel.setOutputMarkupId(true); //this will be use to decorate all submit buttons AttributePrepender isSubmit = new AttributePrepender("data-is_submit", new Model("true"), ""); - + //do not show errors in this feedbacklabel (they will be shown for each component) int[] filteredErrorLevels = new int[]{FeedbackMessage.ERROR}; feedbackPanel.setFilter(new ErrorLevelsFeedbackMessageFilter(filteredErrorLevels)); @@ -382,8 +383,8 @@ public void onClick(AjaxRequestTarget target) { //add ajax submit button final AmpButtonField saveAndSubmit = new AmpButtonField("saveAndSubmit","Save and Submit", AmpFMTypes.MODULE, true) { - - + + @Override protected void onSubmit(final AjaxRequestTarget target, Form form) { processAndUpdateForm(true, am, form, target, this.getButton()); @@ -435,7 +436,7 @@ protected void onSubmit(final AjaxRequestTarget target, Form form) { //we only remove disable on buttons tagged as submit ones //target.appendJavaScript("enableButtons2();"); } - + @Override protected void onError(final AjaxRequestTarget target, Form form) { @@ -451,18 +452,18 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { generateEnableButtonsOnError(attributes); } }; - - - + + + AttributePrepender updateEditors = new AttributePrepender("onclick", new Model("window.onbeforeunload = null; for (instance in CKEDITOR.instances) CKEDITOR.instances[instance].updateElement();disableButton();"), ""); saveAndSubmit.getButton().add(isSubmit); - + AttributePrepender closeEditors = new AttributePrepender("onclick", new Model("$('a[data-is_close=true]:visible').click();"), ""); AttributePrepender clickMonEval = new AttributePrepender("onclick", new Model("$('.mon_eval_button:visible').click();"), ""); AttributePrepender closeDialogs = new AttributePrepender("onclick", new Model( "$('.ui-dialog-content').dialog('close');"), ""); - + saveAndSubmit.getButton().add(new AttributeModifier("class", new Model("sideMenuButtons"))); saveAndSubmit.getButton().add(updateEditors); saveAndSubmit.getButton().add(closeEditors); @@ -471,16 +472,16 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { saveAndSubmit.getButton().setDefaultFormProcessing(false); saveAndSubmit.setAffectedByFreezing(false); activityForm.add(saveAndSubmit); - + AmpAjaxLinkField rejectActivityLink = new AmpAjaxLinkField("saveReject", "Reject Activity", "Reject activity") { @Override protected void onClick(AjaxRequestTarget target) { } - + @Override protected void onBeforeRender() { super.onBeforeRender(); - + AmpAuthWebSession wicketSession = (AmpAuthWebSession) org.apache.wicket.Session.get(); AmpTeamMember ampCurrentMember = wicketSession.getAmpCurrentMember(); this.setVisible(ActivityUtil.canReject(ampCurrentMember, am.getObject().getDraft(), newActivity)); @@ -495,15 +496,17 @@ protected void onBeforeRender() { rejectActivityLink.getButton().add(new AttributeModifier("class", new Model<>("sideMenuButtons rejectButton"))); activityForm.add(rejectActivityLink); - + AmpAjaxLinkField saveAsDraft = new AmpAjaxLinkField("saveAsDraft", "Save as Draft", "Save as Draft") { @Override protected void onClick(AjaxRequestTarget target) { + WebResponse response = (WebResponse)getRequestCycle().getResponse(); + response.setHeader("Access-Control-Allow-Origin", "*"); } }; - + saveAsDraft.getButton().add(isSubmit); - + // saveAsDraft.getButton().add(new AttributeModifier("onclick", "showDraftPanel();disableButton();")); saveAsDraft.getButton().add(new AttributePrepender("onclick", new Model("showDraftPanel();disableButton();"), "")); saveAsDraft.getButton().add(closeEditors); @@ -523,7 +526,7 @@ public void renderHead(Component component, IHeaderResponse response) { response.render(JavaScriptHeaderItem.forReference(new PackageResourceReference(AmpActivityFormFeature.class, "enableDisableButtons.js"))); } }); - + final RadioGroup myDraftOpts = new RadioGroup("draftRedirectedGroup", new Model(GO_TO_DESKTOP)); Radio radioDesktop=new Radio("draftRedirectedDesktop", new Model(GO_TO_DESKTOP)); @@ -551,12 +554,12 @@ protected void onEvent(final AjaxRequestTarget target) { myDraftOpts.add(radioStay); activityForm.add(myDraftOpts); - + final AmpAjaxLinkField cancelLink = new AmpAjaxLinkField("saveAsDraftCanceld", "Cancel", "Cancel") { @Override protected void onClick(AjaxRequestTarget target) { // TODO Auto-generated method stub - + } }; cancelLink.getButton().add(new AttributeModifier("onclick", "hideDraftPanel();enableButtons2();")); @@ -573,7 +576,7 @@ protected void onSubmit(AjaxRequestTarget target, Form form) { onSaveAsDraft(am, feedbackPanel, redirected, new ActionButtonCancelLink(this, cancelLink), target, form); } - + @Override protected void onError(final AjaxRequestTarget target, Form form) { super.onError(target, form); @@ -596,13 +599,13 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { saveAsDraftAction.add(isSubmit); saveAsDraftAction.setAffectedByFreezing(false); activityForm.add(saveAsDraftAction); - + //text area for the message AmpTextAreaFieldPanel rejectMessage = new AmpTextAreaFieldPanel("rejectMessage", new PropertyModel(am,"rejectMessage"), "Reject Message", false); activityForm.add(rejectMessage); //buttons for the reject activity panel //cancelrejectActivity - + AmpAjaxLinkField cancelRejectActivity=new AmpAjaxLinkField("cancelRejectActivity", "Cancel Reject activity", "Cancel") { @Override protected void onClick(AjaxRequestTarget target) { @@ -614,8 +617,8 @@ protected void onClick(AjaxRequestTarget target) { cancelRejectActivity.setVisible(true); cancelRejectActivity.getButton().add(new AttributeModifier("class", new Model("sideMenuButtons"))); activityForm.add(cancelRejectActivity); - - + + AmpButtonField rejectActivityAction = new AmpButtonField("rejectActivityAction", "Reject Activity", AmpFMTypes.MODULE, true) { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { @@ -627,7 +630,7 @@ protected void onError(final AjaxRequestTarget target, Form form) { super.onError(target, form); onErrorSaveAsDraftOrReject(feedbackPanel, target, form); } - + @Override protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { generateEnableButtonsOnError(attributes); @@ -639,13 +642,13 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { rejectActivityAction.getButton().add(new AttributePrepender("onclick", new Model("disableButton();"), "")); rejectActivityAction.getButton().add(updateEditors); rejectActivityAction.add(isSubmit); - activityForm.add(rejectActivityAction); - - - - - - + activityForm.add(rejectActivityAction); + + + + + + // this div will be "submitted" by the autoSaveTimer final WebMarkupContainer autoSaveDiv = new WebMarkupContainer( "autoSaveDiv"); @@ -663,8 +666,8 @@ protected void onSubmit(AjaxRequestTarget target) { op.getEditLockRefresher().setEnabled(false); if (op.getTimer() != null) { op.getTimer().stop(target); - } - + } + am.setObject(am.getObject()); toggleSemanticValidation(false, activityForm, target); // process the form for this request @@ -686,7 +689,7 @@ protected void onSubmit(AjaxRequestTarget target) { autoSaveTimer.restart(target); } } - + } @@ -703,7 +706,7 @@ public boolean getDefaultProcessing() { // will fire int autoSaveSeconds = Integer.parseInt(FeaturesUtil .getGlobalSettingValue(GlobalSettingsConstants.ACTIVITY_AUTO_SAVE_SECONDS)); - + autoSaveTimer = null; if (autoSaveSeconds != 0) { autoSaveTimer = new AbstractAjaxTimerBehavior( @@ -716,8 +719,8 @@ protected void onTimer(AjaxRequestTarget target) { op.getEditLockRefresher().setEnabled(false); if (op.getTimer() != null) { op.getTimer().stop(target); - } - //we disable the stop timer so it doesn't get called after its being processed + } + //we disable the stop timer so it doesn't get called after its being processed this.stop(target); target.appendJavaScript(String.format("$('#%s').click()", autoSaveDiv.getMarkupId())); @@ -748,7 +751,7 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { logframe.getButton().add(new AttributeModifier("class", true, new Model("sideMenuButtons"))); */ //activityForm.add(logframe); - + AmpButtonField preview = new AmpButtonField("preview", "Preview", AmpFMTypes.MODULE, true) { @Override protected void onSubmit(AjaxRequestTarget target, Form form) { @@ -762,7 +765,7 @@ protected void onSubmit(AjaxRequestTarget target, Form form) { + am.getObject().getAmpActivityId() + "~isPreview=1\");"); } } - + @Override protected void onError(AjaxRequestTarget target, Form form) { super.onError(target, form); @@ -784,7 +787,7 @@ protected void updateAjaxAttributes(AjaxRequestAttributes attributes) { preview.getButton().add(isSubmit); preview.setAffectedByFreezing(false); activityForm.add(preview); - + featureList = new ListView("featureList", listModel) { private static final long serialVersionUID = 7218457979728871528L; @Override @@ -796,7 +799,7 @@ protected void populateItem(final ListItem item) { tmp.add(new AttributeModifier("style", "font-size: medium; font-style: bold; color: red; margin: 15px;")); item.add(tmp); } - + String activityFormOnePager = FeaturesUtil.getGlobalSettingValue( GlobalSettingsConstants.ACTIVITY_FORM_ONE_PAGER); if ("false".equals(activityFormOnePager)){ @@ -804,7 +807,7 @@ protected void populateItem(final ListItem item) { item.add(new AttributeModifier("style", "display: none;")); } } - + } }; featureList.setReuseItems(true); @@ -828,7 +831,7 @@ private void processAndUpdateForm(boolean notDraft, IModel a toggleSemanticValidation(notDraft, form, target); form.process(button); - + form.visitChildren(AmpAgreementItemPanel.class,new IVisitor() { @Override @@ -837,7 +840,7 @@ public void component(AmpAgreementItemPanel object, object.validateIsNewAgreementFormClosed(target); visit.dontGoDeeper(); } - + }); form.visitChildren(AbstractTextComponent.class, @@ -846,7 +849,7 @@ public void component(AmpAgreementItemPanel object, public void component(Component component, IVisit objectIVisit) { IModel model = component.getDefaultModel(); AbstractTextComponent atc = (AbstractTextComponent) component; - //logger.error(component.getParent().getId()); + //logger.error(component.getParent().getId()); boolean required = false; List validators = atc.getValidators(); for (IValidator validator : validators) { @@ -1026,7 +1029,7 @@ private double sumUp(Collection collection, int transactionType, Object parent){ return total; } - + protected void formSubmitErrorHandle(Form form, final AjaxRequestTarget target, FeedbackPanel feedbackPanel) { //once an error has happened if in tabsview we process the funding section to //highlight the tabs with errors @@ -1034,8 +1037,8 @@ protected void formSubmitErrorHandle(Form form, final AjaxRequestTarget targe showFundingTabsErrors(form, target); } // visit form children and add to the ajax request the invalid ones - - + + form.visitChildren(FormComponent.class, new IVisitor() { @Override public void component(FormComponent component, IVisit visit) { @@ -1092,7 +1095,7 @@ public void component(FormComponent component, IVisit visit) { protected void saveMethod(AjaxRequestTarget target, IModel am, FeedbackPanel feedbackPanel, boolean draft, Model redirected,boolean rejected) { - + AmpActivityModel a = (AmpActivityModel) am; AmpActivityVersion activity = am.getObject(); Long oldId = activity.getAmpActivityId(); @@ -1101,7 +1104,7 @@ protected void saveMethod(AjaxRequestTarget target, AmpAuthWebSession wicketSession = (AmpAuthWebSession)org.apache.wicket.Session.get(); long currentUserId = wicketSession.getCurrentMember().getMemberId(); activity.setChangeType(ChangeType.MANUAL.toString()); - + AmpTeamMember ampCurrentMember = wicketSession.getAmpCurrentMember(); @@ -1110,13 +1113,13 @@ protected void saveMethod(AjaxRequestTarget target, //Someone else has grabbed the lock ... maybe connection slow and lock refresh timed out throw new RedirectToUrlException(ActivityGatekeeper.buildRedirectLink(String.valueOf(a.getId()), currentUserId)); } - + ActivityUtil.saveActivity((AmpActivityModel) am, draft, rejected); info(TranslatorUtil.getTranslatedText("Activity saved successfully")); /* - * if activity created or created as draft + * if activity created or created as draft * and then saved the message should be sent to the list */ AmpActivityVersion newActivity=am.getObject(); @@ -1127,7 +1130,7 @@ protected void saveMethod(AjaxRequestTarget target, //if validation is off in team setup no messages should be generated String validation = DbUtil.getValidationFromTeamAppSettings(ampCurrentMember.getAmpTeam().getAmpTeamId()); - + if (activity.getDraft() != null && !activity.getDraft() && !(Constants.PROJECT_VALIDATION_OFF.equals(validation))) { if (ActivityUtil.isApproved(newActivity)) { @@ -1161,7 +1164,7 @@ protected void saveMethod(AjaxRequestTarget target, } p.set(1,actId); - //The folllogin exception will provide a redirection + //The folllogin exception will provide a redirection throw new RestartResponseException( new PageProvider( OnePager.class,p),RedirectPolicy.ALWAYS_REDIRECT); @@ -1213,29 +1216,29 @@ public CharSequence getFailureHandler(Component component) { }; attributes.getAjaxCallListeners().add(listener); } - + protected void onSaveAsDraft(final IModel am, final FeedbackPanel feedbackPanel, final Model redirected, final ActionButtonCancelLink actionButtonCancelLink, AjaxRequestTarget target, Form form) { - + target.appendJavaScript("hideDraftPanel();"); - + onSaveAsDraftOrReject(am, feedbackPanel, redirected, actionButtonCancelLink, target, form, false); } - + protected void onReject(final IModel am, final FeedbackPanel feedbackPanel, final Model redirected, final ActionButtonCancelLink actionButtonCancelLink, AjaxRequestTarget target, Form form) { - + target.appendJavaScript("hideRejectActivityPanel();"); - + onSaveAsDraftOrReject(am, feedbackPanel, redirected, actionButtonCancelLink, target, form, true); } - + /** * Method used from saveAsDraft and Reject activity(the only difference between them is that reject prior to saving * the activity changes the status of the activity and sends the messages if the user has chosen to - * + * * @param am * @param feedbackPanel * @param redirected @@ -1247,10 +1250,10 @@ protected void onSaveAsDraftOrReject(final IModel am, final final Model redirected, final ActionButtonCancelLink actionButtonCancelLink, AjaxRequestTarget target, Form form, boolean isRejected) { - + final AmpButtonField actionButton = actionButtonCancelLink.getActionButton(); final AmpAjaxLinkField cancelAction = actionButtonCancelLink.getCancelActionLink(); - + processAndUpdateForm(false, am, form, target, actionButton.getButton()); // only in the eventuality that the title field is valid (is not empty) we proceed with the real save! @@ -1261,12 +1264,12 @@ protected void onSaveAsDraftOrReject(final IModel am, final if (op.getTimer() != null) { op.getTimer().restart(target); } - + target.add(actionButton); target.add(cancelAction); - + onErrorSaveAsDraftOrReject(feedbackPanel, target, form); - + if (autoSaveTimer != null && autoSaveTimer.isStopped()) { autoSaveTimer.restart(target); } @@ -1274,12 +1277,12 @@ protected void onSaveAsDraftOrReject(final IModel am, final //if no error happend and we are rejecting we change the approval status to rejected // send a message to the creator of the activity saveMethod(target, am, feedbackPanel, true, redirected, isRejected); - + if (isRejected) { sendRejectMessage(am); } } - + target.appendJavaScript("enableButtons2();"); } @@ -1292,10 +1295,10 @@ private void sendRejectMessage(IModel activityModel) { AmpActivityVersion activity = activityModel.getObject(); String messageToSend = activity.getRejectMessage(); AmpTeamMember tmTo = activity.getActivityCreator(); - + AmpAuthWebSession wicketSession = (AmpAuthWebSession) org.apache.wicket.Session.get(); TeamMember tmFrom = wicketSession.getCurrentMember(); - + AmpMessage message = new AmpAlert(); String senderName; Long activityId; @@ -1305,24 +1308,24 @@ private void sendRejectMessage(IModel activityModel) { message.setName(TranslatorWorker.translateText("Activity Rejected")); message.setSenderType(MessageConstants.SENDER_TYPE_USER); message.setSenderId(tmFrom.getMemberId()); - + senderName = user.getFirstNames() + " " + user.getLastName() + "<" + user.getEmailUsedForNotification() + ">;" + tmFrom.getTeamName(); message.setSenderName(senderName); - + message.setRelatedActivityId(activityId); - + /*String fullModuleURL=RequestUtils.getFullModuleUrl(request);*/ String objUrl = "/aim/viewActivityPreview.do~activityId=" + activityId; message.setObjectURL(objUrl); - - + + message.setPriorityLevel(MessageConstants.PRIORITY_LEVEL_CRITICAL); if(messageToSend==null){ messageToSend=""; } message.setDescription(messageToSend); - + message.setCreationDate(new Date(System.currentTimeMillis())); message.setDraft(false); @@ -1332,7 +1335,7 @@ private void sendRejectMessage(IModel activityModel) { AmpMessageState state = new AmpMessageState(); state.setMessage(message); state.setSender(tmFrom.getMemberName() + ";" + tmFrom.getTeamName()); - + try { AmpMessageUtil.saveOrUpdateMessageState(state); AmpMessageUtil.createMessageState(message, tmTo); @@ -1340,7 +1343,7 @@ private void sendRejectMessage(IModel activityModel) { logger.error("Cannot create reject message", e); throw new RuntimeException(e); } - + message.addMessageReceiver(tmTo); AmpMessageUtil.saveOrUpdateMessage(message); diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/CustomResourceLinkResourceLink.java b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/CustomResourceLinkResourceLink.java new file mode 100644 index 00000000000..4c45ac03a0e --- /dev/null +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/CustomResourceLinkResourceLink.java @@ -0,0 +1,15 @@ +package org.dgfoundation.amp.onepager.components.features; + +import org.apache.wicket.markup.html.link.ResourceLink; +import org.apache.wicket.request.resource.ResourceReference; + +public class CustomResourceLinkResourceLink extends ResourceLink { + public CustomResourceLinkResourceLink(String id, ResourceReference resourceReference) { + super(id, resourceReference); + } + private ExportExcelResourceReference exportExcelResourceReference; + public void setReference(ExportExcelResourceReference resourceReference) { + this.exportExcelResourceReference=resourceReference; + } + +} diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/ExportExcelResourceReference.java b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/ExportExcelResourceReference.java new file mode 100644 index 00000000000..71479731a82 --- /dev/null +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/ExportExcelResourceReference.java @@ -0,0 +1,108 @@ +package org.dgfoundation.amp.onepager.components.features; + +import org.apache.poi.xssf.usermodel.XSSFRow; +import org.apache.poi.xssf.usermodel.XSSFSheet; +import org.apache.poi.xssf.usermodel.XSSFWorkbook; +import org.apache.wicket.Component; +import org.apache.wicket.request.resource.AbstractResource; +import org.apache.wicket.request.resource.ContentDisposition; +import org.apache.wicket.request.resource.IResource; +import org.apache.wicket.request.resource.ResourceReference; +import org.apache.wicket.util.io.ByteArrayOutputStream; +import org.dgfoundation.amp.onepager.components.ListItem; +import org.dgfoundation.amp.onepager.components.PagingListEditor; +import org.digijava.module.aim.dbentity.AmpStructure; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +public class ExportExcelResourceReference extends ResourceReference { + + private static final Logger logger = LoggerFactory.getLogger(ExportExcelResourceReference.class); + PagingListEditor list; + public void setList(PagingListEditor list) + { + this.list = list; + } + public PagingListEditor getList() + { + return list; + } + public ExportExcelResourceReference() { + super("export-excel"); + } + + @Override + public IResource getResource() { + return new AbstractResource() { + @Override + protected ResourceResponse newResourceResponse(Attributes attributes) { + ResourceResponse response = new ResourceResponse(); + + // Set response metadata + response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); + response.setContentDisposition(ContentDisposition.ATTACHMENT); + response.setFileName("structures.xlsx"); + + if (response.dataNeedsToBeWritten(attributes)) { + try (ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + XSSFWorkbook workbook = new XSSFWorkbook()) { + // Create Excel sheet + XSSFSheet sheet = workbook.createSheet("Structures"); + + // Create header row + XSSFRow headerRow = sheet.createRow(0); + headerRow.createCell(0).setCellValue("Title"); + headerRow.createCell(1).setCellValue("Description"); + headerRow.createCell(2).setCellValue("Latitude"); + headerRow.createCell(3).setCellValue("Longitude"); + + int rowIndex = 1; + for (Component child : getList()) { + if (child instanceof ListItem) { + ListItem listItem = (ListItem) child; + AmpStructure structure = listItem.getModelObject(); + + // Create a new row for each structure + XSSFRow row = sheet.createRow(rowIndex); + if (structure != null) { + createCellIfNotNull(row, 0, structure.getTitle()); + createCellIfNotNull(row, 1, structure.getDescription()); + createCellIfNotNull(row, 2, structure.getLatitude()); + createCellIfNotNull(row, 3, structure.getLongitude()); + } + rowIndex++; + } + } + + // Write workbook content to the output stream + workbook.write(outputStream); + + // Respond with the written content + response.setWriteCallback(new WriteCallback() { + @Override + public void writeData(Attributes attributes) throws IOException { + attributes.getResponse().write(outputStream.toByteArray()); + } + }); + } catch (IOException e) { + logger.error("Error exporting data to Excel", e); + response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + } + } + + return response; + } + }; + } + + // Helper method for creating cells + private void createCellIfNotNull(XSSFRow row, int columnIndex, Object value) { + if (value != null) { + row.createCell(columnIndex).setCellValue(value.toString()); + } + } + +} diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/FileUploadModalPanel.html b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/FileUploadModalPanel.html new file mode 100644 index 00000000000..3244e22bc54 --- /dev/null +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/FileUploadModalPanel.html @@ -0,0 +1,21 @@ + + + + File Upload Modal + + + + +
+
+ + +
+
+ + +
+
+
+ + diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/FileUploadModalPanel.java b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/FileUploadModalPanel.java new file mode 100644 index 00000000000..841b2c664e6 --- /dev/null +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/FileUploadModalPanel.java @@ -0,0 +1,52 @@ +package org.dgfoundation.amp.onepager.components.features; +import org.apache.wicket.ajax.AjaxRequestTarget; +import org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink; +import org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow; +import org.apache.wicket.markup.html.form.Form; +import org.apache.wicket.markup.html.form.upload.FileUpload; +import org.apache.wicket.markup.html.form.upload.FileUploadField; +import org.apache.wicket.markup.html.panel.Panel; +import java.io.File; + +public class FileUploadModalPanel extends Panel { + + private FileUploadField fileUploadField; + + public FileUploadModalPanel(String id, ModalWindow modalWindow) { + super(id); + + // Create the form and mark it as multi-part for file uploads + Form form = new Form<>("uploadForm"); + form.setMultiPart(true); // Necessary for file upload + + // Add file upload field + fileUploadField = new FileUploadField("fileUploadField"); + form.add(fileUploadField); + + // Add AjaxSubmitLink to handle file upload via Ajax + form.add(new AjaxSubmitLink("uploadButton", form) { + protected void onSubmit(AjaxRequestTarget target) { + FileUpload upload = fileUploadField.getFileUpload(); + if (upload != null) { + try { + // Save the uploaded file or process it + File file = new File("/path/to/save/" + upload.getClientFileName()); + upload.writeTo(file); + System.out.println("File uploaded: " + upload.getClientFileName()); + } catch (Exception e) { + e.printStackTrace(); + } + } + // Close the modal window after successful upload + modalWindow.close(target); + } + + protected void onError(AjaxRequestTarget target) { + // Handle error scenario here + System.out.println("File upload failed"); + } + }); + + add(form); + } +} diff --git a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/sections/AmpStructuresFormSectionFeature.html b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/sections/AmpStructuresFormSectionFeature.html index f6f56f4004f..b4864f9ab94 100644 --- a/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/sections/AmpStructuresFormSectionFeature.html +++ b/amp/WEB-INF/src/org/dgfoundation/amp/onepager/components/features/sections/AmpStructuresFormSectionFeature.html @@ -1,11 +1,39 @@ - + + +
+
+ + + + + + + + +
+ +
+
+ +
+
+
+
+
+ + + Download + + +
+ - + @@ -14,12 +42,12 @@ - - - + + + - - + + @@ -27,21 +55,21 @@ + + + + + + + + + javamelody net.bull.javamelody.MonitoringFilter diff --git a/amp/pom.xml b/amp/pom.xml index 2be3156cdb3..8ae0d098824 100644 --- a/amp/pom.xml +++ b/amp/pom.xml @@ -7,7 +7,7 @@ war Aid Management Platform - 6.29.0 + 6.30.0 8.5.73 5.6.11 5.3.28 @@ -1762,4 +1762,4 @@ Development Gateway http://developmentgateway.org - \ No newline at end of file +
TitleDescriptionLatitudeTitleDescriptionLatitude LongitudeShape Shape 
- +
- +
- -
+ +
-
-