sci-types-project: Managing sponsors.
parent
aaaa9d8277
commit
236866d93e
|
|
@ -29,7 +29,8 @@ public class SciProjectAuthoringSteps implements MvcAuthoringSteps {
|
||||||
SciProjectDescriptionStepResources.class,
|
SciProjectDescriptionStepResources.class,
|
||||||
SciProjectDescriptionStepService.class,
|
SciProjectDescriptionStepService.class,
|
||||||
SciProjectFundingStepResources.class,
|
SciProjectFundingStepResources.class,
|
||||||
SciProjectFundingStepService.class
|
SciProjectFundingStepService.class,
|
||||||
|
SciProjectFundingSponsors.class
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,102 @@
|
||||||
|
package org.scientificcms.contenttypes.sciproject.ui;
|
||||||
|
|
||||||
|
import org.librecms.contentsection.ContentItem;
|
||||||
|
import org.librecms.contentsection.ContentItemRepository;
|
||||||
|
import org.librecms.contentsection.ContentSection;
|
||||||
|
import org.librecms.ui.contentsections.ContentSectionsUi;
|
||||||
|
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
|
||||||
|
import org.scientificcms.contenttypes.sciproject.SciProject;
|
||||||
|
import org.scientificcms.contenttypes.sciproject.Sponsoring;
|
||||||
|
import org.scientificcms.contenttypes.sciproject.SponsoringRepository;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import javax.enterprise.context.RequestScoped;
|
||||||
|
import javax.inject.Inject;
|
||||||
|
import javax.transaction.Transactional;
|
||||||
|
import javax.ws.rs.Consumes;
|
||||||
|
import javax.ws.rs.NotFoundException;
|
||||||
|
import javax.ws.rs.POST;
|
||||||
|
import javax.ws.rs.Path;
|
||||||
|
import javax.ws.rs.PathParam;
|
||||||
|
import javax.ws.rs.core.MediaType;
|
||||||
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||||
|
*/
|
||||||
|
@RequestScoped
|
||||||
|
@Path(MvcAuthoringSteps.PATH_PREFIX + "sciproject-funding-sponsors")
|
||||||
|
public class SciProjectFundingSponsors {
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SponsoringRepository sponsoringRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentItemRepository itemRepo;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private ContentSectionsUi sectionsUi;
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/save-order")
|
||||||
|
@Consumes(MediaType.APPLICATION_JSON)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public Response saveOrder(
|
||||||
|
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||||
|
final String sectionIdentifier,
|
||||||
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
||||||
|
final String documentPath,
|
||||||
|
final List<String> order
|
||||||
|
) {
|
||||||
|
final ContentSection contentSection = sectionsUi
|
||||||
|
.findContentSection(sectionIdentifier)
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new NotFoundException(
|
||||||
|
String.format(
|
||||||
|
"No content identifed by %s found.",
|
||||||
|
sectionIdentifier
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
final ContentItem document = itemRepo
|
||||||
|
.findByPath(contentSection, documentPath)
|
||||||
|
.orElseThrow(
|
||||||
|
() -> new NotFoundException(
|
||||||
|
String.format(
|
||||||
|
"No document for path %s in section %s.",
|
||||||
|
documentPath,
|
||||||
|
contentSection.getLabel()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!(document instanceof SciProject)) {
|
||||||
|
throw new NotFoundException(
|
||||||
|
String.format(
|
||||||
|
"No SciProject for path %s in section %s.",
|
||||||
|
documentPath,
|
||||||
|
contentSection.getLabel()
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final Map<Long, Long> orderMap = new HashMap<>();
|
||||||
|
for (int i = 0; i < order.size(); i++) {
|
||||||
|
orderMap.put(Long.parseLong(order.get(i)), (long) i);
|
||||||
|
}
|
||||||
|
|
||||||
|
final SciProject project = (SciProject) document;
|
||||||
|
for (final Sponsoring sponsoring : project.getSponsoring()) {
|
||||||
|
sponsoring.setOrder(orderMap.get(sponsoring.getSponsoringId()));
|
||||||
|
sponsoringRepo.save(sponsoring);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Response.ok().build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
package org.scientificcms.contenttypes.sciproject.ui;
|
package org.scientificcms.contenttypes.sciproject.ui;
|
||||||
|
|
||||||
|
import org.libreccm.api.Identifier;
|
||||||
|
import org.libreccm.api.IdentifierParser;
|
||||||
import org.libreccm.l10n.GlobalizationHelper;
|
import org.libreccm.l10n.GlobalizationHelper;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.ui.BaseUrl;
|
import org.libreccm.ui.BaseUrl;
|
||||||
|
|
@ -74,6 +76,9 @@ public class SciProjectFundingStep extends AbstractMvcAuthoringStep {
|
||||||
@Context
|
@Context
|
||||||
private HttpServletRequest request;
|
private HttpServletRequest request;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private ItemPermissionChecker itemPermissionChecker;
|
private ItemPermissionChecker itemPermissionChecker;
|
||||||
|
|
||||||
|
|
@ -496,7 +501,7 @@ public class SciProjectFundingStep extends AbstractMvcAuthoringStep {
|
||||||
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
||||||
final String documentPath,
|
final String documentPath,
|
||||||
@FormParam("sponsorUuid")
|
@FormParam("sponsorUuid")
|
||||||
final String sponsorUuid,
|
final String sponsorUuidParam,
|
||||||
@FormParam("fundingCode")
|
@FormParam("fundingCode")
|
||||||
final String fundingCode
|
final String fundingCode
|
||||||
) {
|
) {
|
||||||
|
|
@ -509,11 +514,29 @@ public class SciProjectFundingStep extends AbstractMvcAuthoringStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (itemPermissionChecker.canEditItem(getProject())) {
|
if (itemPermissionChecker.canEditItem(getProject())) {
|
||||||
final Optional<Organization> result = assetRepo
|
final Optional<Organization> result;
|
||||||
.findByUuidAndType(sponsorUuid, Organization.class);
|
final Identifier identifier = identifierParser.parseIdentifier(
|
||||||
|
sponsorUuidParam
|
||||||
|
);
|
||||||
|
switch (identifier.getType()) {
|
||||||
|
case UUID:
|
||||||
|
result = assetRepo.findByUuidAndType(
|
||||||
|
identifier.getIdentifier(), Organization.class
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case ID:
|
||||||
|
result = assetRepo.findById(
|
||||||
|
Long.parseLong(identifier.getIdentifier()),
|
||||||
|
Organization.class
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
models.put("sponsorNotFound", sponsorUuidParam);
|
||||||
|
return showStep(sectionIdentifier, documentPath);
|
||||||
|
}
|
||||||
|
|
||||||
if (!result.isPresent()) {
|
if (!result.isPresent()) {
|
||||||
models.put("sponsorNotFound", sponsorUuid);
|
models.put("sponsorNotFound", sponsorUuidParam);
|
||||||
return showStep(sectionIdentifier, documentPath);
|
return showStep(sectionIdentifier, documentPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -582,7 +605,7 @@ public class SciProjectFundingStep extends AbstractMvcAuthoringStep {
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/sponsoring/remove")
|
@Path("/sponsoring/{sponsoringId}/remove")
|
||||||
@Transactional(Transactional.TxType.REQUIRED)
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
@AuthorizationRequired
|
@AuthorizationRequired
|
||||||
public String removeSponsoring(
|
public String removeSponsoring(
|
||||||
|
|
@ -590,7 +613,7 @@ public class SciProjectFundingStep extends AbstractMvcAuthoringStep {
|
||||||
final String sectionIdentifier,
|
final String sectionIdentifier,
|
||||||
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
||||||
final String documentPath,
|
final String documentPath,
|
||||||
@FormParam("sponsoringId")
|
@PathParam("sponsoringId")
|
||||||
final String sponsoringId
|
final String sponsoringId
|
||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,25 @@
|
||||||
<ui:define name="authoringStep">
|
<ui:define name="authoringStep">
|
||||||
<h2>#{SciProjectMessageBundle['funding_step.header']}</h2>
|
<h2>#{SciProjectMessageBundle['funding_step.header']}</h2>
|
||||||
|
|
||||||
|
<c:if test="#{sponsorNotFound != null}">
|
||||||
|
<div class="alert alert-warning">
|
||||||
|
#{SciProjectMessageBundle.getMessage('funding.errors.sponsor_not_found', [sponsorNotFound])}
|
||||||
|
</div>
|
||||||
|
</c:if>
|
||||||
|
|
||||||
|
<template id="sciproject-sponsoring-sort-error-general">
|
||||||
|
<div class="alert alert-danger mt-3" role="alert">
|
||||||
|
#{SciProjectMessageBundle['sponsors.sort.errors.general']}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template id="sciproject-sponsoring-sort-error-save">
|
||||||
|
<div class="alert alert-danger mt-3" role="alert">
|
||||||
|
#{SciProjectMessageBundle['sponsors.sort.errors.save']}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<div id="messages"></div>
|
||||||
|
|
||||||
<librecms:cmsEditorVariants
|
<librecms:cmsEditorVariants
|
||||||
addButtonLabel="#{SciProjectMessageBundle['funding.editor.add_variant']}"
|
addButtonLabel="#{SciProjectMessageBundle['funding.editor.add_variant']}"
|
||||||
addDialogLocaleSelectHelp="#{SciProjectMessageBundle['funding.editor.add.locale.help']}"
|
addDialogLocaleSelectHelp="#{SciProjectMessageBundle['funding.editor.add.locale.help']}"
|
||||||
|
|
@ -72,7 +91,21 @@
|
||||||
name="fundingCode"
|
name="fundingCode"
|
||||||
/>
|
/>
|
||||||
</librecms:assetPicker>
|
</librecms:assetPicker>
|
||||||
<table>
|
<button class="btn btn-secondary sponsoring-save-order-button"
|
||||||
|
disabled="disabled"
|
||||||
|
type="button">
|
||||||
|
<span class="save-icon">
|
||||||
|
<bootstrap:svgIcon icon="save" />
|
||||||
|
</span>
|
||||||
|
<span class="save-spinner d-none">
|
||||||
|
<span aria-hidden="true"
|
||||||
|
class="spinner-border spinner-border-sm"
|
||||||
|
role="status"></span>
|
||||||
|
</span>
|
||||||
|
<span>#{SciProjectMessageBundle['sponsoring.order.save']}</span>
|
||||||
|
</button>
|
||||||
|
<table id="sciproject-sponsoring-table"
|
||||||
|
data-saveUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@sciproject-funding-sponsors/save-order">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">#{SciProjectMessageBundle['sponsoring.cols.sponsor']}</th>
|
<th scope="col">#{SciProjectMessageBundle['sponsoring.cols.sponsor']}</th>
|
||||||
|
|
@ -84,27 +117,40 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<c:forEach items="#{SciProjectFundingSponsoring.sponsoring}"
|
<c:forEach items="#{SciProjectFundingSponsoring.sponsoring}"
|
||||||
var="sponsoring">
|
var="sponsoring">
|
||||||
<tr id="#{sponsoring.sponsoringId}">
|
<tr class="sciproject-sponsor"
|
||||||
<td>#{sponsoring.sponsor}</td>
|
id="#{sponsoring.sponsoringId}"
|
||||||
|
data-id="#{sponsoring.sponsoringId}">
|
||||||
|
<td>
|
||||||
|
<c:if test="#{CmsSelectedDocumentModel.canEdit}">
|
||||||
|
<button class="btn btn-secondary cms-sort-handle mr-2"
|
||||||
|
type="button">
|
||||||
|
<bootstrap:svgIcon icon="arrows-move" />
|
||||||
|
<span class="sr-only">#{SciProjectMessageBundle['sponsoring.move.button']}</span>
|
||||||
|
</button>
|
||||||
|
</c:if>
|
||||||
|
#{sponsoring.sponsor}
|
||||||
|
</td>
|
||||||
<td>#{sponsoring.fundingCode}</td>
|
<td>#{sponsoring.fundingCode}</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-secondary"
|
<button class="btn btn-secondary"
|
||||||
data-toggle="modal"
|
data-toggle="modal"
|
||||||
data-target="#sponsoring-edit-dialog"
|
data-target="#sponsoring-#{sponsoring.sponsoringId}-edit-dialog"
|
||||||
type="button">
|
type="button">
|
||||||
<bootstrap:svgIcon icon="pen" />
|
<bootstrap:svgIcon icon="pen" />
|
||||||
<span>#{SciProjectMessageBundle['sponsoring.edit.label']}</span>
|
<span>#{SciProjectMessageBundle['sponsoring.edit.label']}</span>
|
||||||
</button>
|
</button>
|
||||||
<div aria-hidden="true"
|
<div aria-hidden="true"
|
||||||
aria-labelledby="sponsoring-edit-dialog-title"
|
aria-labelledby="sponsoring-#{sponsoring.sponsoringId}-edit-dialog-title"
|
||||||
class="modal fade"
|
class="modal fade"
|
||||||
id="spoonsoring-edit-dialog"
|
id="sponsoring-#{sponsoring.sponsoringId}-edit-dialog"
|
||||||
tabindex="-1">
|
tabindex="-1">
|
||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<form class="modal-content">
|
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@sciproject-funding/sponsoring/edit/#{sponsoring.sponsoringId}"
|
||||||
|
class="modal-content"
|
||||||
|
method="post">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h4 class="modal-title"
|
<h4 class="modal-title"
|
||||||
id="sponsoring-edit-dialog-title">
|
id="sponsoring-#{sponsoring.sponsoringId}-edit-dialog-title">
|
||||||
#{SciProjectMessageBundle['sponsoring.edit.title']}
|
#{SciProjectMessageBundle['sponsoring.edit.title']}
|
||||||
</h4>
|
</h4>
|
||||||
<button
|
<button
|
||||||
|
|
@ -115,14 +161,13 @@
|
||||||
<bootstrap:svgIcon icon="x"/>
|
<bootstrap:svgIcon icon="x"/>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<bootstrap:formGroupText
|
<bootstrap:formGroupText
|
||||||
help="#{SciProjectMessageBundle['sponsoring.fundingcode.help']}"
|
help="#{SciProjectMessageBundle['sponsoring.fundingcode.help']}"
|
||||||
inputId="fundingcode"
|
inputId="fundingcode"
|
||||||
label="#{SciProjectMessageBundle['sponsoring.fundingcode.label']}"
|
label="#{SciProjectMessageBundle['sponsoring.fundingcode.label']}"
|
||||||
name="fundingCode"
|
name="fundingCode"
|
||||||
|
value="#{sponsoring.fundingCode}"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
|
|
@ -136,15 +181,17 @@
|
||||||
#{SciProjectMessageBundle['sponsoring.edit.submit']}
|
#{SciProjectMessageBundle['sponsoring.edit.submit']}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<libreccm:deleteDialog
|
<libreccm:deleteDialog
|
||||||
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@sciproject-funding/sponsoring/remove"
|
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@sciproject-funding/sponsoring/#{sponsoring.sponsoringId}/remove"
|
||||||
buttonText="#{SciProjectMessageBundle['sponsoring.remove.label']}"
|
buttonText="#{SciProjectMessageBundle['sponsoring.remove.label']}"
|
||||||
cancelLabel="#{SciProjectMessageBundle['sponsoring.remove.cancel']}"
|
cancelLabel="#{SciProjectMessageBundle['sponsoring.remove.cancel']}"
|
||||||
confirmLabel="#{SciProjectMessageBundle['sponsoring.remove.confirm']}"
|
confirmLabel="#{SciProjectMessageBundle['sponsoring.remove.confirm']}"
|
||||||
dialogId="sponsoring-remove-dialog"
|
dialogId="sponsoring-#{sponsoring.sponsoringId}-remove-dialog"
|
||||||
dialogTitle="#{SciProjectMessageBundle['sponsoring.remove.title']}"
|
dialogTitle="#{SciProjectMessageBundle['sponsoring.remove.title']}"
|
||||||
message="#{SciProjectMessageBundle.getMessage('sponsoring.remove.message', [sponsoring.sponsor])}"
|
message="#{SciProjectMessageBundle.getMessage('sponsoring.remove.message', [sponsoring.sponsor])}"
|
||||||
/>
|
/>
|
||||||
|
|
@ -154,10 +201,10 @@
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<ui:define name="scripts">
|
|
||||||
<script src="#{request.contextPath}/assets/@content-sections/sciproject-sponsoring.js"></script>
|
|
||||||
</ui:define>
|
</ui:define>
|
||||||
|
|
||||||
|
<ui:define name="scripts">
|
||||||
|
<script src="#{request.contextPath}/assets/@sciproject/sciproject-sponsoring.js"></script>
|
||||||
</ui:define>
|
</ui:define>
|
||||||
|
|
||||||
</ui:composition>
|
</ui:composition>
|
||||||
|
|
|
||||||
|
|
@ -181,3 +181,8 @@ contact.add.title=Add contact
|
||||||
memberships.add.title=Add member
|
memberships.add.title=Add member
|
||||||
description_step.errors.person_not_found=Selected person {0} not found.
|
description_step.errors.person_not_found=Selected person {0} not found.
|
||||||
description_step.errors.illegal_member_status_value=The status value {0} is not valid.
|
description_step.errors.illegal_member_status_value=The status value {0} is not valid.
|
||||||
|
sponsoring.order.save=Save order
|
||||||
|
sponsoring.move.button=Drag to order sponsors
|
||||||
|
funding.errors.sponsor_not_found=The selected sponsor {0} was not found.
|
||||||
|
sponsors.sort.errors.general=Error sorting sponsors
|
||||||
|
sponsors.sort.errors.save=Failed to save order of sponsors.
|
||||||
|
|
|
||||||
|
|
@ -181,3 +181,8 @@ contact.add.title=Kontakt hinzuf\u00fcgen
|
||||||
memberships.add.title=Mitglied hinzuf\u00fcgen
|
memberships.add.title=Mitglied hinzuf\u00fcgen
|
||||||
description_step.errors.person_not_found=Die ausgew\u00e4hlte Person {0} wurde nicht gefunden.
|
description_step.errors.person_not_found=Die ausgew\u00e4hlte Person {0} wurde nicht gefunden.
|
||||||
description_step.errors.illegal_member_status_value=Der Status {0} wird nicht unterst\u00fctzt.
|
description_step.errors.illegal_member_status_value=Der Status {0} wird nicht unterst\u00fctzt.
|
||||||
|
sponsoring.order.save=Sortierung speichern
|
||||||
|
sponsoring.move.button=Zum sortieren Sponsoren ziehen
|
||||||
|
funding.errors.sponsor_not_found=Der ausgew\u00e4hlte Sponsor {0} wurde nicht gefunden.
|
||||||
|
sponsors.sort.errors.general=Fehler beim Sortieren der Sponsoren
|
||||||
|
sponsors.sort.errors.save=Speichern der Sortierung der Sponsoren fehlgeschlagen.
|
||||||
|
|
|
||||||
|
|
@ -106,7 +106,7 @@ function saveOrder() {
|
||||||
spinner?.classList.toggle("d-none");
|
spinner?.classList.toggle("d-none");
|
||||||
}
|
}
|
||||||
throw Error(
|
throw Error(
|
||||||
`Failed to save attachments order. Response status: ${response.status}, statusText: ${response.statusText}`
|
`Failed to save contacts order. Response status: ${response.status}, statusText: ${response.statusText}`
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
@ -122,7 +122,7 @@ function saveOrder() {
|
||||||
saveIcon?.classList.toggle("d-none");
|
saveIcon?.classList.toggle("d-none");
|
||||||
spinner?.classList.toggle("d-none");
|
spinner?.classList.toggle("d-none");
|
||||||
}
|
}
|
||||||
throw new Error(`Failed to save attachments order: ${error}`);
|
throw new Error(`Failed to save contacts order: ${error}`);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,155 @@
|
||||||
|
import Sortable, { SortableEvent } from "sortablejs";
|
||||||
|
|
||||||
|
let sponsoringSortable: Sortable;
|
||||||
|
|
||||||
|
document.addEventListener("DOMContentLoaded", function (event) {
|
||||||
|
const sponsoringTable = document.querySelector(
|
||||||
|
"#sciproject-sponsoring-table tbody"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (sponsoringTable) {
|
||||||
|
sponsoringSortable = initSponsoringTable(
|
||||||
|
sponsoringTable as HTMLElement
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveOrderButtons = document.querySelectorAll(
|
||||||
|
".sponsoring-save-order-button"
|
||||||
|
);
|
||||||
|
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||||
|
saveOrderButtons[i].addEventListener("click", saveOrder);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function initSponsoringTable(sponsoringTable: HTMLElement): Sortable {
|
||||||
|
return new Sortable(sponsoringTable, {
|
||||||
|
animation: 150,
|
||||||
|
group: "sciproject-sponsor",
|
||||||
|
handle: ".cms-sort-handle",
|
||||||
|
onEnd: enableSaveButtons,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function enableSaveButtons(event: SortableEvent) {
|
||||||
|
const saveOrderButtons = document.querySelectorAll(
|
||||||
|
".sponsoring-save-order-button"
|
||||||
|
);
|
||||||
|
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||||
|
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||||
|
i
|
||||||
|
] as HTMLButtonElement;
|
||||||
|
saveOrderButton.disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function saveOrder() {
|
||||||
|
const sponsoringTable = document.querySelector(
|
||||||
|
"#sciproject-sponsoring-table"
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!sponsoringTable) {
|
||||||
|
showGeneralError();
|
||||||
|
throw Error("sciproject-sponsoring-table not found.");
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveUrl = sponsoringTable.getAttribute("data-saveUrl");
|
||||||
|
if (!saveUrl) {
|
||||||
|
showGeneralError();
|
||||||
|
throw Error(
|
||||||
|
"data-saveUrl on sciproject-sponsoring-table is missing or empty"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const saveOrderButtons = document.querySelectorAll(
|
||||||
|
".sponsoring-save-order-button"
|
||||||
|
);
|
||||||
|
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||||
|
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||||
|
i
|
||||||
|
] as HTMLButtonElement;
|
||||||
|
saveOrderButton.disabled = true;
|
||||||
|
const saveIcon = saveOrderButton.querySelector("save-icon");
|
||||||
|
const spinner = saveOrderButton.querySelector(".save-spinner");
|
||||||
|
saveIcon?.classList.toggle("d-none");
|
||||||
|
spinner?.classList.toggle("d-none");
|
||||||
|
}
|
||||||
|
|
||||||
|
const headers = new Headers();
|
||||||
|
headers.append("Content-Type", "application/json");
|
||||||
|
fetch(saveUrl, {
|
||||||
|
credentials: "include",
|
||||||
|
body: JSON.stringify(sponsoringSortable.toArray()),
|
||||||
|
headers,
|
||||||
|
method: "POST",
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
if (response.ok) {
|
||||||
|
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||||
|
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||||
|
i
|
||||||
|
] as HTMLButtonElement;
|
||||||
|
const saveIcon =
|
||||||
|
saveOrderButton.querySelector(".save-icon");
|
||||||
|
const spinner =
|
||||||
|
saveOrderButton.querySelector(".save-spinner");
|
||||||
|
saveIcon?.classList.toggle("d-none");
|
||||||
|
spinner?.classList.toggle("d-none");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
showSaveError();
|
||||||
|
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||||
|
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||||
|
i
|
||||||
|
] as HTMLButtonElement;
|
||||||
|
saveOrderButton.disabled = false;
|
||||||
|
const saveIcon =
|
||||||
|
saveOrderButton.querySelector(".save-icon");
|
||||||
|
const spinner =
|
||||||
|
saveOrderButton.querySelector(".save-spinner");
|
||||||
|
saveIcon?.classList.toggle("d-none");
|
||||||
|
spinner?.classList.toggle("d-none");
|
||||||
|
}
|
||||||
|
throw Error(
|
||||||
|
`Failed to save sponsor order. Response status: ${response.status}, statusText: ${response.statusText}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
showSaveError();
|
||||||
|
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||||
|
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||||
|
i
|
||||||
|
] as HTMLButtonElement;
|
||||||
|
saveOrderButton.disabled = false;
|
||||||
|
const saveIcon = saveOrderButton.querySelector(".save-icon");
|
||||||
|
const spinner = saveOrderButton.querySelector(".save-spinner");
|
||||||
|
saveIcon?.classList.toggle("d-none");
|
||||||
|
spinner?.classList.toggle("d-none");
|
||||||
|
}
|
||||||
|
throw new Error(`Failed to save sponsor order: ${error}`);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function showGeneralError(): void {
|
||||||
|
const alertTemplate = document.querySelector(
|
||||||
|
"#sciproject-sponsoring-sort-error-general"
|
||||||
|
) as HTMLTemplateElement;
|
||||||
|
const alert = alertTemplate.content.cloneNode(true) as Element;
|
||||||
|
|
||||||
|
const container = document.querySelector("#messages");
|
||||||
|
if (container) {
|
||||||
|
container.appendChild(alert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function showSaveError(): void {
|
||||||
|
const alertTemplate = document.querySelector(
|
||||||
|
"#sciproject-sponsoring-sort-error-save"
|
||||||
|
) as HTMLTemplateElement;
|
||||||
|
const alert = alertTemplate.content.cloneNode(true) as Element;
|
||||||
|
|
||||||
|
const container = document.querySelector("#messages");
|
||||||
|
if (container) {
|
||||||
|
container.appendChild(alert);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -5,11 +5,8 @@ module.exports = {
|
||||||
chunkIds: false
|
chunkIds: false
|
||||||
},
|
},
|
||||||
entry: {
|
entry: {
|
||||||
// "sciproject-description": "./src/main/typescript/sciproject-description.ts",
|
|
||||||
"sciproject-contacts": "./src/main/typescript/sciproject-contacts.ts",
|
"sciproject-contacts": "./src/main/typescript/sciproject-contacts.ts",
|
||||||
// "sciproject-fundingtext": "./src/main/typescript/sciproject-fundingtext.ts",
|
"sciproject-sponsoring": "./src/main/typescript/sciproject-sponsoring.ts"
|
||||||
// "sciproject-fundingvolume": "./src/main/typescript/sciproject-fundingvolume.ts",
|
|
||||||
//"sciproject-sponsoring": "./src/main/typescript/sciproject-sponsoring.ts"
|
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
filename: "[name].js",
|
filename: "[name].js",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue