JavaScript functions for ordering attachment lists and attachments
parent
9b95f72c5c
commit
3b3a241ba2
|
|
@ -65,6 +65,15 @@ public class ItemAttachmentManager {
|
|||
return Optional.empty();
|
||||
}
|
||||
}
|
||||
|
||||
@Transactional(Transactional.TxType.REQUIRED)
|
||||
public void save(final ItemAttachment<?> attachment) {
|
||||
if (attachment.getAttachmentId() == 0) {
|
||||
entityManager.persist(attachment);
|
||||
} else {
|
||||
entityManager.merge(attachment);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the provided {@link Asset} to the provided {@link AttachmentList}.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
public class RelatedInfoStepAttachmentOrder {
|
||||
|
||||
private List<String> attachmentListsOrder;
|
||||
|
||||
private Map<String, List<String>> attachmentsOrder;
|
||||
|
||||
public List<String> getAttachmentListsOrder() {
|
||||
return Collections.unmodifiableList(attachmentListsOrder);
|
||||
}
|
||||
|
||||
public void setAttachmentListsOrder(final List<String> attachmentListsOrder) {
|
||||
this.attachmentListsOrder = new ArrayList<>(attachmentListsOrder);
|
||||
}
|
||||
|
||||
public Map<String, List<String>> getAttachmentsOrder() {
|
||||
return Collections.unmodifiableMap(attachmentsOrder);
|
||||
}
|
||||
|
||||
public void setAttachmentsOrder(
|
||||
final Map<String, List<String>> attachmentsOrder
|
||||
) {
|
||||
this.attachmentsOrder = attachmentsOrder
|
||||
.entrySet()
|
||||
.stream()
|
||||
.collect(
|
||||
Collectors.toMap(
|
||||
entry -> entry.getKey(),
|
||||
entry -> new ArrayList<>(entry.getValue())
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format(
|
||||
"attachmentListsOrder = %s, "
|
||||
+ "attachmentsOrder = %s",
|
||||
Objects.toString(attachmentListsOrder),
|
||||
Objects.toString(attachmentsOrder)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*
|
||||
* Copyright (C) 2021 LibreCCM Foundation.
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||
* MA 02110-1301 USA
|
||||
*/
|
||||
package org.librecms.ui.contentsections.documents;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
import org.librecms.contentsection.AttachmentListRepository;
|
||||
import org.librecms.contentsection.ContentItemRepository;
|
||||
import org.librecms.contentsection.ItemAttachmentManager;
|
||||
import org.librecms.ui.contentsections.ContentSectionsUi;
|
||||
import org.w3c.dom.events.Event;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import javax.enterprise.context.RequestScoped;
|
||||
import javax.inject.Inject;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.PathParam;
|
||||
import javax.ws.rs.core.Response;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
|
||||
*/
|
||||
@RequestScoped
|
||||
@Path(MvcAuthoringSteps.PATH_PREFIX + "relatedinfo")
|
||||
public class RelatedInfoStepService {
|
||||
|
||||
private static final Logger LOGGER = LogManager.getLogger(
|
||||
RelatedInfoStepService.class
|
||||
);
|
||||
|
||||
@Inject
|
||||
private AttachmentListRepository attachmentListRepo;
|
||||
|
||||
@Inject
|
||||
private ItemAttachmentManager attachmentManager;
|
||||
|
||||
@Inject
|
||||
private ContentItemRepository itemRepo;
|
||||
|
||||
@Inject
|
||||
private ContentSectionsUi sectionsUi;
|
||||
|
||||
public Response saveOrder(
|
||||
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
|
||||
final String sectionIdentifier,
|
||||
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
|
||||
final String documentPath,
|
||||
final RelatedInfoStepAttachmentOrder order
|
||||
) {
|
||||
LOGGER.info("order = {}", order);
|
||||
|
||||
return Response.ok().build();
|
||||
|
||||
// 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()
|
||||
// )
|
||||
// )
|
||||
// );
|
||||
//
|
||||
// //final Map<String, Integer> attachmentListIndexes =
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -15,14 +15,6 @@
|
|||
<bootstrap:svgIcon icon="plus-circle" />
|
||||
<span>#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.add.button.label']}</span>
|
||||
</button>
|
||||
<button class="btn btn-secondary"
|
||||
data-toggle="modal"
|
||||
data-target="#order-attachment-lists-dialog"
|
||||
type="button"
|
||||
>
|
||||
<bootstrap:svgIcon icon="arrows-move" />
|
||||
<span>#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.sort.button.label']}</span>
|
||||
</button>
|
||||
</div>
|
||||
<div aria-hidden="true"
|
||||
aria-labelledby="add-attachment-list-dialog-title"
|
||||
|
|
@ -81,8 +73,17 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<ul class="cms-attachment-lists">
|
||||
<li class="cms-attachment-list mb-3">
|
||||
<div>
|
||||
<button class="btn btn-secondary save-order-button"
|
||||
disabled="disabled"
|
||||
type="button">
|
||||
<bootstrap:svgIcon icon="save" />
|
||||
<span>#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.order.save']}</span>
|
||||
</button>
|
||||
</div>
|
||||
<ul class="cms-attachment-lists mt-3">
|
||||
<li class="cms-attachment-list mb-3"
|
||||
data-id="34aba2e6-a9b2-4b82-9889-c7ea591b6faf">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="cms-attachment-list-name">List 1</div>
|
||||
<div class="cms-attachmentlist-buttons">
|
||||
|
|
@ -108,8 +109,10 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="cms-attachments mt-3">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<ul class="cms-attachments mt-3"
|
||||
data-list-uuid="34aba2e6-a9b2-4b82-9889-c7ea591b6faf">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="a871c22b-f533-49eb-be3e-3600f4e83180">
|
||||
<div class="cms-attachment-label">Attachment 1a</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -134,7 +137,8 @@
|
|||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="6ab14e1e-dc9a-4a39-9514-9bea68bcd357">
|
||||
<div class="cms-attachment-label">Attachment 1b</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -159,7 +163,8 @@
|
|||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="f3a1d656-fb4e-4ba8-9f5c-e605700e7c5f">
|
||||
<div class="cms-attachment-label">Attachment 1c</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -186,7 +191,8 @@
|
|||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<li class="cms-attachment-list mb-3">
|
||||
<li class="cms-attachment-list mb-3"
|
||||
data-id="b962a838-e25e-4987-8058-6205692d2d92">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="cms-attachment-list-name">List 2</div>
|
||||
<div class="cms-attachmentlist-buttons">
|
||||
|
|
@ -212,8 +218,10 @@
|
|||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="cms-attachments mt-3">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<ul class="cms-attachments mt-3"
|
||||
data-list-uuid="b962a838-e25e-4987-8058-6205692d2d92">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="296495bd-fbf6-4956-a047-5fa3400df367">
|
||||
<div class="cms-attachment-label">Attachment 2a</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -238,7 +246,8 @@
|
|||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="89d89ffd-a322-43a2-81b9-d127503bf52b">
|
||||
<div class="cms-attachment-label">Attachment 2b</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -263,7 +272,8 @@
|
|||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="f85193f2-38fc-4f34-b6fa-4ed6f4e30f69">
|
||||
<div class="cms-attachment-label">Attachment 2c</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -288,7 +298,8 @@
|
|||
</button>
|
||||
</div>
|
||||
</li>
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between">
|
||||
<li class="cms-attachment mb-3 d-flex justify-content-between"
|
||||
data-id="a063c64d-3da6-4948-837c-137bf3511579">
|
||||
<div class="cms-attachment-label">Attachment 2d</div>
|
||||
<div class="cms-attachment-buttons">
|
||||
<button class="btn btn-secondary cms-sort-handle"
|
||||
|
|
@ -316,7 +327,14 @@
|
|||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
<div>
|
||||
<button class="btn btn-secondary save-order-button"
|
||||
disabled="disabled"
|
||||
type="button">
|
||||
<bootstrap:svgIcon icon="save" />
|
||||
<span>#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.order.save']}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<ul>
|
||||
<c:forEach items="#{CmsRelatedInfoStep.attachmentLists}"
|
||||
|
|
|
|||
|
|
@ -1,11 +1,34 @@
|
|||
// import Sortable = require("sortablejs")
|
||||
import Sortable from "sortablejs";
|
||||
import Sortable, { SortableEvent } from "sortablejs";
|
||||
|
||||
interface RelatedInfoStepAttachmentOrder {
|
||||
attachmentListsOrder: string[];
|
||||
attachmentsOrder: {
|
||||
[key: string]: string[];
|
||||
};
|
||||
movedAttachments: MovedAttachment[];
|
||||
}
|
||||
|
||||
interface MovedAttachment {
|
||||
attachmentUuid: string;
|
||||
fromListUuid: string;
|
||||
toListUuid: string;
|
||||
}
|
||||
|
||||
const movedAttachments: MovedAttachment[] = [];
|
||||
|
||||
let attachmentsListSortable: Sortable;
|
||||
let attachmentsSortables: {
|
||||
[key: string]: Sortable;
|
||||
} = {};
|
||||
|
||||
document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const attachmentLists = document.querySelectorAll(".cms-attachment-lists");
|
||||
const attachmentLists = document.querySelector(".cms-attachment-lists");
|
||||
|
||||
for (let i = 0; i < attachmentLists.length; i++) {
|
||||
initAttachmentList(attachmentLists[i] as HTMLElement);
|
||||
if (attachmentLists) {
|
||||
attachmentsListSortable = initAttachmentLists(
|
||||
attachmentLists as HTMLElement
|
||||
);
|
||||
}
|
||||
|
||||
const attachments = document.querySelectorAll(".cms-attachments");
|
||||
|
|
@ -13,21 +36,109 @@ document.addEventListener("DOMContentLoaded", function (event) {
|
|||
for (let i = 0; i < attachments.length; i++) {
|
||||
initAttachments(attachments[i] as HTMLElement);
|
||||
}
|
||||
|
||||
const saveOrderButtons = document.querySelectorAll(".save-order-button");
|
||||
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||
saveOrderButtons[i].addEventListener("click", saveOrder);
|
||||
}
|
||||
});
|
||||
|
||||
function initAttachmentList(attachmentList: HTMLElement) {
|
||||
new Sortable(attachmentList, {
|
||||
function initAttachmentLists(attachmentList: HTMLElement): Sortable {
|
||||
return new Sortable(attachmentList, {
|
||||
animation: 150,
|
||||
group: "cms-attachment-lists",
|
||||
handle: ".cms-sort-handle"
|
||||
handle: ".cms-sort-handle",
|
||||
onEnd: enableSaveButton
|
||||
});
|
||||
}
|
||||
|
||||
function initAttachments(attachments: HTMLElement) {
|
||||
new Sortable(attachments,
|
||||
{
|
||||
animation: 150,
|
||||
group: "cms-attachments",
|
||||
handle: ".cms-sort-handle"
|
||||
});
|
||||
function initAttachments(attachments: HTMLElement): Sortable {
|
||||
const sortable = new Sortable(attachments, {
|
||||
animation: 150,
|
||||
group: "cms-attachments",
|
||||
handle: ".cms-sort-handle",
|
||||
onEnd: moveAttachment
|
||||
});
|
||||
|
||||
const listUuid = attachments.getAttribute("data-list-uuid");
|
||||
if (listUuid === null) {
|
||||
throw Error("attachments with data-list-uuid attribute found.");
|
||||
}
|
||||
|
||||
attachmentsSortables[listUuid] = sortable;
|
||||
|
||||
return sortable;
|
||||
}
|
||||
|
||||
function enableSaveButton(event: SortableEvent) {
|
||||
const saveOrderButtons = document.querySelectorAll(".save-order-button");
|
||||
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||
i
|
||||
] as HTMLButtonElement;
|
||||
saveOrderButton.disabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
function moveAttachment(event: SortableEvent) {
|
||||
// console.log("event.from:");
|
||||
// console.dir(event.from);
|
||||
// console.log("event.to:");
|
||||
// console.dir(event.to);
|
||||
// console.log("event.item:");
|
||||
// console.dir(event.item);
|
||||
|
||||
const fromListUuid = event.from.getAttribute("data-list-uuid");
|
||||
if (!fromListUuid) {
|
||||
throw Error(
|
||||
"An attachment was moved, but the list from which the attachment was removed has no data-id attribute."
|
||||
);
|
||||
}
|
||||
const toListUuid = event.to.getAttribute("data-list-uuid");
|
||||
if (!toListUuid) {
|
||||
throw Error(
|
||||
"An attachment was moved, but the list to which the attachment was removed has no data-id attribute."
|
||||
);
|
||||
}
|
||||
|
||||
if (fromListUuid !== toListUuid) {
|
||||
const attachmentUuid = event.item.getAttribute("data-id");
|
||||
if (!attachmentUuid) {
|
||||
throw Error(
|
||||
"An attachment was moved, but the attachment was removed has no dat-id attribute."
|
||||
);
|
||||
}
|
||||
|
||||
const movedAttachment: MovedAttachment = {
|
||||
fromListUuid,
|
||||
toListUuid,
|
||||
attachmentUuid
|
||||
};
|
||||
movedAttachments.push(movedAttachment);
|
||||
}
|
||||
|
||||
enableSaveButton(event);
|
||||
}
|
||||
|
||||
function saveOrder() {
|
||||
const attachmentOrder: RelatedInfoStepAttachmentOrder = {
|
||||
attachmentListsOrder: attachmentsListSortable.toArray(),
|
||||
attachmentsOrder: {},
|
||||
movedAttachments
|
||||
};
|
||||
|
||||
for (let key in attachmentsSortables) {
|
||||
attachmentOrder.attachmentsOrder[key] =
|
||||
attachmentsSortables[key].toArray();
|
||||
}
|
||||
|
||||
console.dir(attachmentOrder);
|
||||
|
||||
const saveOrderButtons = document.querySelectorAll("save-order-button");
|
||||
for (let i = 0; i < saveOrderButtons.length; i++) {
|
||||
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
|
||||
i
|
||||
] as HTMLButtonElement;
|
||||
saveOrderButton.disabled = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue