Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
ccbcf4b
Ad import export structures buttons
brianbrix Oct 1, 2024
4661655
Ad import export structures buttons
brianbrix Oct 2, 2024
da65a34
Ad import export structures buttons
brianbrix Oct 2, 2024
af64f8b
Ad import export structures buttons
brianbrix Oct 3, 2024
5e96f3f
Ad import export structures buttons
brianbrix Oct 4, 2024
26fd0d7
Ad import export structures buttons
brianbrix Oct 4, 2024
8897dda
Ad import export structures buttons
brianbrix Oct 4, 2024
35e7f55
Add import export structures buttons
brianbrix Oct 6, 2024
0c38bc1
Import button color
brianbrix Oct 8, 2024
d13e4a0
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
e35889c
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
b14ca23
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
23f05c2
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
b5c2f77
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
cddc9f2
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
a7d570d
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
64710e5
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
4efac49
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
ac17a61
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
a368cf5
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
a925a5c
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
6bda795
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
964d352
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
82f28d0
GGW-369: Resolve project saving ajax issue
brianbrix Nov 6, 2024
26c05ba
GGW-369: Structures section styling
brianbrix Nov 7, 2024
32b470b
GGW-369: Structures section styling
brianbrix Nov 7, 2024
b188988
GGW-369: Structures section styling
brianbrix Nov 7, 2024
516e766
GGW-369: Structures section styling
brianbrix Nov 7, 2024
42d6ea9
GGW-369: Structures section styling
brianbrix Nov 7, 2024
4e3d3ed
GGW-369: Structures section styling
brianbrix Nov 7, 2024
7ca9109
GGW-369 arrange colors
jdeanquin-dg Nov 11, 2024
bf2927a
GGW-369 arrange colors
jdeanquin-dg Nov 11, 2024
563c0a6
AMP-31212 : Enhance security by securing cookies and ensuring coss-si…
brianbrix Sep 16, 2026
f258f39
AMP-31212 : Fixing failing docker build
brianbrix Sep 16, 2026
9c62ce9
AMP-31212 : Fixing failing docker build
brianbrix Sep 16, 2026
4d6f010
AMP-31212 : Wrongly formatted patch
brianbrix Sep 16, 2026
9db5021
Remove HttpOnly setting from cookie
brianbrix Oct 1, 2026
e715e5f
Change SameSite cookie policy from strict to lax
brianbrix Oct 1, 2026
bc47814
Failing to load assets
brianbrix Oct 1, 2026
103c23c
Failing to load assets
brianbrix Oct 1, 2026
3b68b90
Failing to load assets
brianbrix Oct 1, 2026
09f0ee7
Failing to load assets
brianbrix Oct 1, 2026
153fd4b
Secure cookies in HttpLoginManager
brianbrix Oct 1, 2026
53f13f1
Upgrade tomcat to v9
brianbrix Oct 1, 2026
5571752
Downgrade back to tomcat 8.5.100
brianbrix Oct 1, 2026
3937b68
Set secure flag for userNameCookie to true
brianbrix Oct 1, 2026
941fe4a
Set session cookie to secure mode
brianbrix Oct 1, 2026
4a8df0d
Merge pull request #4515 from devgateway/fix/AMP-31205/PIDC-Security-…
jdeanquin-dg Oct 1, 2026
32ef2e8
Merge branch 'develop' into feature/GGW-369/Export-Import-Structures
brianbrix Oct 6, 2026
c1883c3
Refactor Excel export to use AmpStructure list directly
brianbrix Oct 6, 2026
64abb3e
Refactor loop to iterate over AmpStructure list
brianbrix Oct 6, 2026
910940a
Close file stream automatically
brianbrix Oct 7, 2026
88c1bc7
Merge remote-tracking branch 'origin/feature/GGW-369/Export-Import-St…
brianbrix Oct 7, 2026
332ef3c
Refactor resource panel setup in AmpStructuresFormSection
brianbrix Oct 7, 2026
524dec3
Copilot comments resolution
brianbrix Oct 7, 2026
841e8c6
Merge remote-tracking branch 'origin/feature/GGW-369/Export-Import-St…
brianbrix Oct 7, 2026
393cc4f
Potential fix for pull request finding 'Secure login cookie breaks pe…
brianbrix Oct 7, 2026
637cb43
Add check for empty sheet in AmpStructuresFormSectionFeature
brianbrix Oct 7, 2026
c3aa0da
Add missing shape column
brianbrix Oct 7, 2026
0ba2907
Merge remote-tracking branch 'origin/feature/GGW-369/Export-Import-St…
brianbrix Oct 7, 2026
e08f406
Check for structure title duplicates
brianbrix Oct 7, 2026
5b8e49c
Allign structures section correctly
brianbrix Oct 7, 2026
9f32bf7
Avoid automatic upload on file chooser
brianbrix Oct 7, 2026
d7ad2b2
Use rest endpoitn to upload structures
brianbrix Oct 7, 2026
67d965b
Use rest endpoint to upload files
brianbrix Oct 7, 2026
6b4453a
Use rest endpoint to upload files
brianbrix Oct 7, 2026
2d453de
Change upload status message
brianbrix Oct 7, 2026
fd23745
Correct upload status message
brianbrix Oct 8, 2026
399f228
Change downloadLink addition to rc.add method
brianbrix Oct 8, 2026
3f17829
Add stagedUploadResponse to target after setting model
brianbrix Oct 8, 2026
ef918e1
Fix method call to add exportStructures
brianbrix Oct 8, 2026
c002b69
Update file size validation for uploads
brianbrix Oct 8, 2026
070e3fa
Expire staged uploads and limit file size and number
brianbrix Oct 8, 2026
7f2542d
Merge remote-tracking branch 'origin/feature/GGW-369/Export-Import-St…
brianbrix Oct 8, 2026
4757e87
Refactor byte limit calculation for uploads
brianbrix Oct 8, 2026
30cbb66
Fix content length check for workbook upload
brianbrix Oct 8, 2026
eb750d1
Expire staged uploads and limit file size and number
brianbrix Oct 8, 2026
813172c
Add exception for exceeding workbook size limit
brianbrix Oct 8, 2026
fb806f8
Merge remote-tracking branch 'origin/feature/GGW-369/Export-Import-St…
brianbrix Oct 8, 2026
ff0bc22
Wrongly placed container error
brianbrix Oct 8, 2026
3a43de1
Wrongly placed container error
brianbrix Oct 8, 2026
74542bb
Wrongly placed container error
brianbrix Oct 8, 2026
6ce49d1
Remove deleteOnExit for staged upload file
brianbrix Oct 8, 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
2 changes: 1 addition & 1 deletion amp/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ RUN --mount=type=cache,target=/root/.m2 \
&& rm -rf target; \
fi

FROM tomcat:8.5.79-jdk8
FROM tomcat:8.5.100-jdk8-temurin-focal

RUN apt-get update \
&& apt-get install -y apt-transport-https ca-certificates curl gnupg --no-install-recommends \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,7 @@ const SkeletonTable: React.FC<SkeletonTableProps> = (props) => {
>
<i className="fa fa-download" />
{' '}
<span>{t('amp.indicatormanager:export-csv')}</span>
<span>{t('amp.indicatormanager:exportCsv')}</span>
</ExportCSVButton>
</div>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"amp.indicatormanager:sectors": "Sectors",
"amp.indicatormanager:all-sectors": "All Sectors",
"amp.indicatormanager:search": "Search by name or code",
"amp.indicatormanager:export-csv": "Export CSV",
"amp.indicatormanager:exportCsv": "Export CSV",
"amp.indicatormanager:table-header-id": "ID",
"amp.indicatormanager:table-header-code": "Code",
"amp.indicatormanager:table-header-indicator-name": "Indicator Name",
Expand Down Expand Up @@ -35,7 +35,7 @@
"amp.indicatormanager:enable-target": "Enable Target Values Input",
"amp.indicatormanager:base-values": "Base Values",
"amp.indicatormanager:base-date": "Base Date",
"amp.indicatormanager:target-date": "Target Date",
"amp.indicatormanager:targetDate": "Target Date",
"amp.indicatormanager:actual-date": "Actual Date",
"amp.indicatormanager:target-values": "Target Values",
"amp.indicatormanager:original-value": "Original Value",
Expand Down Expand Up @@ -93,7 +93,7 @@
"amp.indicatormanager:errors-revised-base-value-invalid": "Revised base value must be greater than original base value",
"amp.indicatormanager:errors-revised-base-date-invalid": "Revised base date must be greater than or equal to original base date",
"amp.indicatormanager:errors-revised-target-value-invalid": "Revised target value must be greater than original target value",
"amp.indicatormanager:errors-revised-target-date-invalid": "Revised target date must be greater than or equal to original target date",
"amp.indicatormanager:errorsRevisedTargetDateInvalid": "Revised target date must be greater than or equal to original target date",
"amp.indicatormanager:errors-program-is-required": "Program is required",
"amp.indicatormanager:true": "True",
"amp.indicatormanager:false": "False",
Expand All @@ -114,7 +114,7 @@
"amp.outcomeoutput:cancel": "Cancel",
"amp.outcomeoutput:add-new-outcome": "Add New Outcome",
"amp.outcomeoutput:add-new-output": "Add New Output",
"amp.outcomeoutput:export-csv": "Export CSV",
"amp.outcomeoutput:exportCsv": "Export CSV",
"amp.outcomeoutput:search-placeholder": "Search Outcomes",
"amp.outcomeoutput:management-title": "Outcome and Output Management",
"amp.indicatormanager:core-info": "Core Indicator Information",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,7 @@ const OutcomeOutputManagementPage: React.FC = () => {
</Button>
{' '}
<Button variant="secondary" className={styles.export_button} onClick={handleExportCSV}>
<i className="fa fa-download" /> {t('amp.outcomeoutput:export-csv')}
<i className="fa fa-download" /> {t('amp.outcomeoutput:exportCsv')}
</Button>
</div>
</Col>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const translatedIndicatorValidationSchema = (translations: DefaultTransla
revisedValue: Yup.number().optional().nullable(),
revisedValueDate: Yup.date().optional().nullable().when('originalValueDate', (originalValueDate: any) => {
if (originalValueDate) {
return Yup.date().min(originalValueDate, translations["amp.indicatormanager:errors-revised-target-date-invalid"]).optional().nullable();
return Yup.date().min(originalValueDate, translations["amp.indicatormanager:errorsRevisedTargetDateInvalid"]).optional().nullable();
}
return Yup.date().optional().nullable();
}),
Expand Down
11 changes: 5 additions & 6 deletions amp/context.xml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<?xml version="1.0"?>

<Context path="/" debug="0" reloadable="false" unloadDelay="4000" swallowOutput="true"
<Context path="/" debug="0" reloadable="false" unloadDelay="4000" swallowOutput="true" useHttpOnly="true"
allowLinking="true" antiJARLocking="" antiResourceLocking="" clearReferencesStopTimerThreads="true"
clearReferencesThreadLocals="true" jndiExceptionOnFailedWrite="false" processTlds="false">
<Environment name="hostname" value="" type="java.lang.String"/>
<Environment name="hostname" value="" type="java.lang.String"/>

<!-- SameSite=Lax: browser will not send the session cookie on cross-site
POST/PUT/DELETE requests, providing CSRF protection for all endpoints
including /rest/** without requiring any token in requests. -->
<CookieProcessor sameSiteCookies="lax" />

<!-- Strict prevents session cookies from being sent in cross-site requests. -->
<CookieProcessor sameSiteCookies="strict" />
Comment thread
brianbrix marked this conversation as resolved.
<!-- PostgreSQL connection -->
<Resource factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
defaultTransactionIsolation="READ_COMMITTED"
Expand Down
2 changes: 1 addition & 1 deletion amp/docker/server.xml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@

<Connector port="8080" URIEncoding="UTF-8" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443"
redirectPort="8443" server="AMP"
relaxedQueryChars="|{}" />

<Engine name="Catalina" defaultHost="localhost">
Expand Down
2 changes: 1 addition & 1 deletion amp/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<name>Aid Management Platform</name>
<properties>
<wicketVersion>6.29.0</wicketVersion>
<tomcatVersion>8.5.73</tomcatVersion>
<tomcatVersion>8.5.100</tomcatVersion>
<springSecurityVersion>5.6.11</springSecurityVersion>
<springVersion>5.3.28</springVersion>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public void init() {
IS_DEVELOPMENT_MODE = true;
}


//getResourceSettings().setStripJavaScriptCommentsAndWhitespace(true);
//getResourceSettings().setAddLastModifiedTimeToResourceReferenceUrl(true);
//TODO:
Expand Down Expand Up @@ -278,16 +279,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;
Expand Down
Original file line number Diff line number Diff line change
@@ -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
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,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;
Expand All @@ -57,6 +58,7 @@
import org.dgfoundation.amp.onepager.components.features.subsections.AmpDonorFundingInfoSubsectionFeature;
import org.dgfoundation.amp.onepager.components.fields.*;
import org.dgfoundation.amp.onepager.helper.ActionButtonCancelLink;
import org.dgfoundation.amp.onepager.helper.TemporaryActivityDocument;
import org.dgfoundation.amp.onepager.models.AmpActivityModel;
import org.dgfoundation.amp.onepager.models.TranslationDecoratorModel;
import org.dgfoundation.amp.onepager.translation.TranslatorUtil;
Expand All @@ -83,6 +85,7 @@
import org.digijava.module.message.triggers.ApprovedActivityTrigger;
import org.digijava.module.message.triggers.NotApprovedActivityTrigger;
import org.digijava.module.message.util.AmpMessageUtil;
import org.digijava.module.contentrepository.helper.StagedResourceUploadStore;

import java.util.*;

Expand Down Expand Up @@ -501,6 +504,8 @@ protected void onBeforeRender() {
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", "*");
}
};

Expand Down Expand Up @@ -1125,7 +1130,29 @@ protected void saveMethod(AjaxRequestTarget target,
throw new RedirectToUrlException(ActivityGatekeeper.buildRedirectLink(String.valueOf(a.getId()), currentUserId));
}

ActivityUtil.saveActivity((AmpActivityModel) am, draft, rejected);
HashSet<TemporaryActivityDocument> pendingResources = wicketSession.getMetaData(OnePagerConst.RESOURCES_NEW_ITEMS);
if (pendingResources != null) {
for (TemporaryActivityDocument resource : pendingResources) {
if (resource.getStagedUploadId() != null
&& StagedResourceUploadStore.get(SessionUtil.getCurrentServletRequest(),
resource.getStagedUploadId()) == null) {
feedbackPanel.error(TranslatorUtil.getTranslatedText(
"A selected document upload is no longer available. Remove it and upload the file again."));
target.add(feedbackPanel);
return;
}
}
}

try {
ActivityUtil.saveActivity((AmpActivityModel) am, draft, rejected);
} catch (ActivityUtil.StagedResourceSaveException e) {
logger.error("Unable to save a staged activity resource.", e);
feedbackPanel.error(TranslatorUtil.getTranslatedText(
"A related document could not be saved. The activity was not saved; retry or remove the document."));
target.add(feedbackPanel);
return;
}

info(TranslatorUtil.getTranslatedText("Activity saved successfully"));

Expand Down
Original file line number Diff line number Diff line change
@@ -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<Void> extends ResourceLink<Void> {
public CustomResourceLinkResourceLink(String id, ResourceReference resourceReference) {
super(id, resourceReference);
}
private ExportExcelResourceReference exportExcelResourceReference;
public void setReference(ExportExcelResourceReference resourceReference) {
this.exportExcelResourceReference=resourceReference;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
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<AmpStructure> list;
public void setList(PagingListEditor<AmpStructure> list)
{
this.list = list;
}
public PagingListEditor<AmpStructure> 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 (AmpStructure structure : getList().getModel().getObject()) {
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());
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
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.panel.Panel;
import org.apache.wicket.model.IModel;
import org.apache.wicket.model.Model;
import org.apache.wicket.util.upload.FileItem;
import org.dgfoundation.amp.onepager.components.upload.FileUploadPanel;

public class FileUploadModalPanel extends Panel {

public FileUploadModalPanel(String id, ModalWindow modalWindow) {
super(id);

Form<?> form = new Form<>("uploadForm");
IModel<FileItem> fileItemModel = new Model<>();
form.add(new FileUploadPanel("fileUploadField", "new", fileItemModel));

form.add(new AjaxSubmitLink("uploadButton", form) {
protected void onSubmit(AjaxRequestTarget target) {
if (fileItemModel.getObject() != null) {
modalWindow.close(target);
}
}
});

add(form);
}
}
Loading
Loading