Added templates, JavaScript and translations for the media step. Slight renaming for related info step to avoid conflicts.

pull/10/head
Jens Pelzetter 2021-08-05 20:53:56 +02:00
parent f4b73670af
commit c75d718978
16 changed files with 1058 additions and 77 deletions

View File

@ -24,7 +24,7 @@ package org.librecms.ui.contentsections.documents.media;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class MediaAttachmentDto { public class MediaDto {
/** /**
* The ID of the attachment. * The ID of the attachment.

View File

@ -25,8 +25,8 @@ import java.util.List;
/** /**
* A data transfer object used by the template for the listing of the * A data transfer object used by the template for the listing of the
* {@link AttachmentList}s containing media attachments of a * {@link AttachmentList}s containing media media of a
* {@link ContentItem}. {@link ContentItem}.
* *
* @see MediaStep * @see MediaStep
* *
@ -69,7 +69,7 @@ public class MediaListDto {
/** /**
* The @link{ItemAttachment}s associated with the {@link AttachmentList}. * The @link{ItemAttachment}s associated with the {@link AttachmentList}.
*/ */
private List<MediaAttachmentDto> attachments; private List<MediaDto> media;
public long getListId() { public long getListId() {
return listId; return listId;
@ -119,12 +119,12 @@ public class MediaListDto {
this.description = description; this.description = description;
} }
public List<MediaAttachmentDto> getAttachments() { public List<MediaDto> getMedia() {
return Collections.unmodifiableList(attachments); return Collections.unmodifiableList(media);
} }
public void setAttachments(final List<MediaAttachmentDto> attachments) { public void setMedia(final List<MediaDto> media) {
this.attachments = new ArrayList<>(attachments); this.media = new ArrayList<>(media);
} }
} }

View File

@ -242,7 +242,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
@POST @POST
@Path("/medialists/@add") @Path("/medialists/@add")
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public String addMedia( public String addMediaList(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier, final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
@ -450,7 +450,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
} }
/** /**
* Removes an media list and all media attachments of the list. * Removes an media list and all media of the list.
* *
* @param sectionIdentifier * @param sectionIdentifier
* @param documentPath * @param documentPath
@ -520,7 +520,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
@POST @POST
@Path("/medialists/{mediaListIdentifier}/title/@add") @Path("/medialists/{mediaListIdentifier}/title/@add")
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public String addAttachmentListTitle( public String addMediaListTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier, final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
@ -640,7 +640,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
@Path( @Path(
"/medialists/{mediaListIdentifier}/title/@remove/{locale}") "/medialists/{mediaListIdentifier}/title/@remove/{locale}")
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public String removeAttachmentListTitle( public String removeMediaListTitle(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier, final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
@ -698,7 +698,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
@POST @POST
@Path("/medialists/{mediaListIdentifier}/description/@add") @Path("/medialists/{mediaListIdentifier}/description/@add")
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public String addAttachmentListDescription( public String addMediaListDescription(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier, final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
@ -873,12 +873,12 @@ public class MediaStep extends AbstractMvcAuthoringStep {
* @param mediaIdentifierParam The identifier of the media asset to use for * @param mediaIdentifierParam The identifier of the media asset to use for
* the media attachment. * the media attachment.
* *
* @return A redirect to the list of attachment lists and attachments. * @return A redirect to the list of media lists and mediaa.
*/ */
@POST @POST
@Path("/medialists/{mediaListIdentifier}/attachments/@create") @Path("/medialists/{mediaListIdentifier}/media/@create")
@Transactional(Transactional.TxType.REQUIRED) @Transactional(Transactional.TxType.REQUIRED)
public String createAttachment( public String linkMedia(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier, final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME) @PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
@ -936,7 +936,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
models models
.put("section", getContentSection().getLabel()); .put("section", getContentSection().getLabel());
models.put("assetUuid", mediaIdentifierParam); models.put("assetUuid", mediaIdentifierParam);
return "org/librecms/ui/contentsection/documents/asset-not-found.xhtml"; return "org/librecms/ui/contentsection/documents/media-not-found.xhtml";
} }
final Asset asset = assetResult.get(); final Asset asset = assetResult.get();
@ -1329,11 +1329,11 @@ public class MediaStep extends AbstractMvcAuthoringStep {
final AttachmentList attachmentList final AttachmentList attachmentList
) { ) {
final MediaListDto dto = new MediaListDto(); final MediaListDto dto = new MediaListDto();
dto.setAttachments( dto.setMedia(
attachmentList attachmentList
.getAttachments() .getAttachments()
.stream() .stream()
.map(this::buildMediaAttachmentDto) .map(this::buildMediaDto)
.collect(Collectors.toList()) .collect(Collectors.toList())
); );
dto.setDescription( dto.setDescription(
@ -1359,18 +1359,18 @@ public class MediaStep extends AbstractMvcAuthoringStep {
* Helper function for building a {@link ItemAttachmentDto} for an * Helper function for building a {@link ItemAttachmentDto} for an
* {@link ItemAttachment}. * {@link ItemAttachment}.
* *
* @param itemAttachment The {@link ItemAttachment} from which the * @param mediaAttachment The {@link ItemAttachment} from which the
* {@link ItemAttachmentDto} is build. * {@link ItemAttachmentDto} is build.
* *
* @return The {@link ItemAttachmentDto}. * @return The {@link MediaDto}.
*/ */
private MediaAttachmentDto buildMediaAttachmentDto( private MediaDto buildMediaDto(
final ItemAttachment<?> itemAttachment final ItemAttachment<?> mediaAttachment
) { ) {
final MediaAttachmentDto dto = new MediaAttachmentDto(); final MediaDto dto = new MediaDto();
dto.setAssetType( dto.setAssetType(
Optional Optional
.ofNullable(itemAttachment.getAsset()) .ofNullable(mediaAttachment.getAsset())
.map(Asset::getClass) .map(Asset::getClass)
.map(clazz -> assetTypesManager.getAssetTypeInfo(clazz)) .map(clazz -> assetTypesManager.getAssetTypeInfo(clazz))
.map(info -> info.getAssetClass().getName()) .map(info -> info.getAssetClass().getName())
@ -1378,7 +1378,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
); );
dto.setAssetTypeLabel( dto.setAssetTypeLabel(
Optional Optional
.ofNullable(itemAttachment.getAsset()) .ofNullable(mediaAttachment.getAsset())
.map(Asset::getClass) .map(Asset::getClass)
.map(clazz -> assetTypesManager.getAssetTypeInfo(clazz)) .map(clazz -> assetTypesManager.getAssetTypeInfo(clazz))
.map( .map(
@ -1388,15 +1388,15 @@ public class MediaStep extends AbstractMvcAuthoringStep {
); );
dto.setAssetUuid( dto.setAssetUuid(
Optional Optional
.ofNullable(itemAttachment.getAsset()) .ofNullable(mediaAttachment.getAsset())
.map(Asset::getUuid) .map(Asset::getUuid)
.orElse(null) .orElse(null)
); );
dto.setAttachmentId(itemAttachment.getAttachmentId()); dto.setAttachmentId(mediaAttachment.getAttachmentId());
dto.setSortKey(itemAttachment.getSortKey()); dto.setSortKey(mediaAttachment.getSortKey());
dto.setTitle( dto.setTitle(
Optional Optional
.ofNullable(itemAttachment.getAsset()) .ofNullable(mediaAttachment.getAsset())
.map( .map(
asset -> globalizationHelper.getValueFromLocalizedString( asset -> globalizationHelper.getValueFromLocalizedString(
asset.getTitle() asset.getTitle()
@ -1404,7 +1404,7 @@ public class MediaStep extends AbstractMvcAuthoringStep {
) )
.orElse("") .orElse("")
); );
dto.setUuid(itemAttachment.getUuid()); dto.setUuid(mediaAttachment.getUuid());
return dto; return dto;
} }

View File

@ -29,30 +29,30 @@ import java.util.stream.Collectors;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class MediaStepAttachmentOrder { public class MediaStepMediaOrder {
private List<String> attachmentListsOrder; private List<String> mediaListsOrder;
private Map<String, List<String>> attachmentsOrder; private Map<String, List<String>> mediaOrder;
private List<MovedAttachment> movedAttachments; private List<MovedMedia> movedMedia;
public List<String> getAttachmentListsOrder() { public List<String> getMediaListsOrder() {
return Collections.unmodifiableList(attachmentListsOrder); return Collections.unmodifiableList(mediaListsOrder);
} }
public void setAttachmentListsOrder(final List<String> attachmentListsOrder) { public void setMediaListsOrder(final List<String> mediaListsOrder) {
this.attachmentListsOrder = new ArrayList<>(attachmentListsOrder); this.mediaListsOrder = new ArrayList<>(mediaListsOrder);
} }
public Map<String, List<String>> getAttachmentsOrder() { public Map<String, List<String>> getMediaOrder() {
return Collections.unmodifiableMap(attachmentsOrder); return Collections.unmodifiableMap(mediaOrder);
} }
public void setAttachmentsOrder( public void setMediaOrder(
final Map<String, List<String>> attachmentsOrder final Map<String, List<String>> mediaOrder
) { ) {
this.attachmentsOrder = attachmentsOrder this.mediaOrder = mediaOrder
.entrySet() .entrySet()
.stream() .stream()
.collect( .collect(
@ -63,23 +63,22 @@ public class MediaStepAttachmentOrder {
); );
} }
public List<MovedAttachment> getMovedAttachments() { public List<MovedMedia> getMovedMedia() {
return Collections.unmodifiableList(movedAttachments); return Collections.unmodifiableList(movedMedia);
} }
public void setMovedAttachments(final List<MovedAttachment> movedAttachments) { public void setMovedMedia(final List<MovedMedia> movedMedia) {
this.movedAttachments = new ArrayList<>(movedAttachments); this.movedMedia = new ArrayList<>(movedMedia);
} }
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format("mediaListsOrder = %s, "
"attachmentListsOrder = %s, " + "mediaOrder = %s, "
+ "attachmentsOrder = %s, " + "movedMedia = %s",
+ "movedAttachments = %s", Objects.toString(mediaListsOrder),
Objects.toString(attachmentListsOrder), Objects.toString(mediaOrder),
Objects.toString(attachmentsOrder), Objects.toString(movedMedia)
Objects.toString(movedAttachments)
); );
} }

View File

@ -72,7 +72,7 @@ public class MediaStepService {
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,
final MediaStepAttachmentOrder order final MediaStepMediaOrder order
) { ) {
final ContentSection contentSection = sectionsUi final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier) .findContentSection(sectionIdentifier)
@ -99,7 +99,7 @@ public class MediaStepService {
final List<AttachmentList> attachmentLists = document.getAttachments(); final List<AttachmentList> attachmentLists = document.getAttachments();
final List<String> attachmentListsOrder = order final List<String> attachmentListsOrder = order
.getAttachmentListsOrder(); .getMediaListsOrder();
if (attachmentListsOrder.size() != attachmentLists.size()) { if (attachmentListsOrder.size() != attachmentLists.size()) {
throw new BadRequestException( throw new BadRequestException(
@ -135,7 +135,7 @@ public class MediaStepService {
} }
for (final Map.Entry<String, List<String>> attachmentsOrder : order for (final Map.Entry<String, List<String>> attachmentsOrder : order
.getAttachmentsOrder().entrySet()) { .getMediaOrder().entrySet()) {
final AttachmentList attachmentList = document final AttachmentList attachmentList = document
.getAttachments() .getAttachments()
.stream() .stream()

View File

@ -22,20 +22,20 @@ package org.librecms.ui.contentsections.documents.media;
* *
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a> * @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/ */
public class MovedAttachment { public class MovedMedia {
private String attachmentUuid; private String mediaUuid;
private String fromListUuid; private String fromListUuid;
private String toListUuid; private String toListUuid;
public String getAttachmentUuid() { public String getMediaUuid() {
return attachmentUuid; return mediaUuid;
} }
public void setAttachmentUuid(final String attachmentUuid) { public void setMediaUuid(final String mediaUuid) {
this.attachmentUuid = attachmentUuid; this.mediaUuid = mediaUuid;
} }
public String getFromListUuid() { public String getFromListUuid() {

View File

@ -0,0 +1,145 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:define name="authoringStep">
<div class="d-flex mb-3">
<a class="btn btn-secondary mr-3"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media">
<bootstrap:svgIcon icon="arrow-left-circle" />
<span>#{CmsDefaultStepsMessageBundle['contentsection.documents.media.medialist.back']}</span>
</a>
<h3>
#{CmsDefaultStepsMessageBundle.getMessage('media.medialist.details.title', [CmsMediaListDetailsModel.name])}
</h3>
</div>
<p>
<span>#{CmsDefaultStepsMessageBundle['media.medialist.details.name.label']}: </span>
#{CmsMediaListDetailsModel.name}
<button class="btn btn-primary"
data-toggle="modal"
data-target="#name-edit-dialog"
type="button">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialist.details.name.edit']}</span>
</button>
</p>
<div aria-hidden="true"
aria-labelledby="name-edit-dialog-title"
id="name-edit-dialog"
class="modal fade"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/@update"
class="modal-content"
method="post">
<div class="modal-header">
<h4 id="name-edit-dialog-title">
#{CmsDefaultStepsMessageBundle.getMessage('media.medialist.details.name_edit_dialog.title', [CmsMediaListDetailsModel.name])}
</h4>
<button aria-label="#{CmsDefaultStepsMessageBundle['media.medialist.details.name_edit_dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x-circle" />
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupText
help="#{CmsDefaultStepsMessageBundle['media.medialist.details.name_edit_dialog.name.help']}"
inputId="name"
label="#{CmsDefaultStepsMessageBundle['media.medialist.details.name_edit_dialog.name.label']}"
name="listName"
pattern="[A-Za-z0-9\-_]*"
required="true"
value="#{CmsMediaListDetailsModel.name}" />
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{CmsDefaultStepsMessageBundle['media.medialist.details.name_edit_dialog.close']}
</button>
<button class="btn btn-success"
type="submit">
#{CmsDefaultStepsMessageBundle['media.medialist.details.name_edit_dialog.save']}
</button>
</div>
</form>
</div>
</div>
<libreccm:localizedStringEditor
addButtonLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add_button.label']}"
addDialogCancelLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.cancel']}"
addDialogLocaleSelectHelp="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.locale.help']}"
addDialogLocaleSelectLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.locale.label']}"
addDialogSubmitLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.submit']}"
addDialogTitle="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.title']}"
addDialogValueHelp="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.value.help']}"
addDialogValueLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.add.value.label']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/title/@add"
editButtonLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.edit_button.label']}"
editDialogCancelLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.edit.cancel']}"
editDialogSubmitLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.edit.submit']}"
editDialogTitle="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.edit.title']}"
editDialogValueHelp="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.edit.value.help']}"
editDialogValueLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/title/@edit"
editorId="list-title-editor"
hasUnusedLocales="#{!CmsMediaListDetailsModel.unusedTitleLocales.isEmpty()}"
objectIdentifier="#{CmsMediaListDetailsModel.name}"
readOnly="#{!CmsMediaListDetailsModel.canEdit}"
removeButtonLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.remove_button.label']}"
removeDialogCancelLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.remove.cancel']}"
removeDialogSubmitLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.remove.submit']}"
removeDialogText="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.remove.text']}"
removeDialogTitle="#{CmsDefaultStepsMessageBundle['media.medialist.details.title.remove.title']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/title/@remove"
title="#{CmsDefaultStepsMessageBundle['media.medialist.details.title_editor.title']}"
unusedLocales="#{CmsMediaListDetailsModel.unusedTitleLocales}"
values="#{CmsMediaListDetailsModel.titles}"
/>
<libreccm:localizedStringEditor
addButtonLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add_button.label']}"
addDialogCancelLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.cancel']}"
addDialogLocaleSelectHelp="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.locale.help']}"
addDialogLocaleSelectLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.locale.label']}"
addDialogSubmitLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.submit']}"
addDialogTitle="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.title']}"
addDialogValueHelp="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.value.help']}"
addDialogValueLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.add.value.label']}"
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/description/@add"
editButtonLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.edit_button.label']}"
editDialogCancelLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.edit.cancel']}"
editDialogSubmitLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.edit.submit']}"
editDialogTitle="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.edit.title']}"
editDialogValueHelp="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.edit.value.help']}"
editDialogValueLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.edit.value.label']}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/description/@edit"
editorId="list-description-editor"
hasUnusedLocales="#{!CmsMediaListDetailsModel.unusedDescriptionLocales.isEmpty()}"
objectIdentifier="#{CmsMediaListDetailsModel.name}"
removeButtonLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.remove_button.label']}"
removeDialogCancelLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.remove.cancel']}"
removeDialogSubmitLabel="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.remove.submit']}"
removeDialogText="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.remove.text']}"
removeDialogTitle="#{CmsDefaultStepsMessageBundle['media.medialist.details.description.remove.title']}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{CmsMediaListDetailsModel.name}/description/@remove"
title="#{CmsDefaultStepsMessageBundle['media.medialist.details.description_editor.title']}"
unusedLocales="#{CmsMediaListDetailsModel.unusedDescriptionLocales}"
useTextarea="true"
values="#{CmsMediaListDetailsModel.descriptions}"
/>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,36 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/document.xhtml">
<ui:param name="activePage" value="document" />
<ui:param name="title" value="#{CmsDefaultStepsMessageBundle['media.medialists.media.not_found.title']}" />
<ui:define name="breadcrumb">
<ui:include src="document-breadcrumbs.xhtml" />
<li aria-current="page" class="breadcrumb-item">
#{CmsDefaultStepsMessageBundle['contentsection.document.media.breadcrumb']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<div class="alert alert-danger" role="alert">
#{CmsDefaultStepsMessageBundle.getMessage('media.medialists.media.not_found.message', [section, assetUuid])}
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,324 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:librecms="http://xmlns.jcp.org/jsf/composite/components/librecms"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/authoringstep.xhtml">
<ui:define name="authoringStep">
<template id="cms-sort-media-error-general">
<div class="alert alert-danger mt-3" role="alert">
#{CmsDefaultStepsMessageBundle['media.sortmedia.errors.general']}
</div>
</template>
<template id="cms-sort-media-error-save">
<div class="alert alert-danger mt-3" role="alert">
#{CmsDefaultStepsMessageBundle['media.sortmedia.errors.save']}
</div>
</template>
<div class="text-right">
<button class="btn btn-primary"
data-toggle="modal"
data-target="#add-media-list-dialog"
type="button">
<bootstrap:svgIcon icon="plus-circle" />
<span>#{CmsDefaultStepsMessageBundle['media.medialists.add.button.label']}</span>
</button>
</div>
<div aria-hidden="true"
aria-labelledby="add-media-list-dialog-title"
class="modal fade"
id="add-media-list-dialog"
tabindex="-1">
<div class="modal-dialog">
<form action="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/@add"
class="modal-content"
method="post">
<div class="modal-header">
<h3 class="modal-title"
id="add-media-list-dialog-title">#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.title']}</h3>
<button aria-label="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x-circle" />
</button>
</div>
<div class="modal-body">
<bootstrap:formGroupText
help="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.name.help']}"
inputId="#add-media-list-name"
label="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.name.label']}"
name="listName"
pattern="[A-Za-z0-9\-_]*"
required="true"
/>
<bootstrap:formGroupText
help="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.title.help']}"
inputId="#add-media-list-title"
label="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.title.label']}"
name="listTitle"
/>
<bootstrap:formGroupTextarea
help="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.description.help']}"
inputId="#add-media-list-name"
label="#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.description.label']}"
name="listDescription"
/>
</div>
<div class="modal-footer">
<button class="btn btn-warning"
data-dismiss="modal"
type="button">
#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.close']}
</button>
<button class="btn btn-success"
type="submit">
#{CmsDefaultStepsMessageBundle['media.medialists.add.dialog.add_list']}
</button>
</div>
</form>
</div>
</div>
<div>
<button class="btn btn-secondary media-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 class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.order.save.inprogress']}</span>
</span>
<span>#{CmsDefaultStepsMessageBundle['media.medialists.order.save']}</span>
</button>
</div>
<div id="messages"></div>
<ul class="cms-media-lists mt-3 list-group"
data-baseUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media-service/save-order">
<c:forEach items="#{CmsMediaStep.mediaLists}"
var="list">
<li class="cms-media-list mb-3 list-group-item list-group-item-primary"
data-id="#{list.uuid}">
<div class="d-flex justify-content-between">
<div>#{list.name}</div>
<div class="cms-medialist-buttons d-flex">
<button class="btn btn-secondary cms-sort-handle mr-2"
type="button">
<bootstrap:svgIcon icon="arrows-move" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.move.button']}"</span>
</button>
<button class="btn btn-secondary mx-2"
data-toggle="modal"
data-target="#media-list-#{list.name}-info"
type="button">
<bootstrap:svgIcon icon="info-circle" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.info.button']}"</span>
</button>
<div aria-hidden="true"
aria-labelledby="medialist-#{list.name}-info-title"
class="modal fade"
id="media-list-#{list.name}-info"
tabindex="-1">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title"
id="medialist-#{list.name}-info-title">
#{CmsDefaultStepsMessageBundle.getMessage('media.medialists.info.dialog.title', [list.name])}
</h3>
<button
aria-label="#{CmsDefaultStepsMessageBundle['media.medialists.info.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-body">
<dl>
<dt>#{CmsDefaultStepsMessageBundle['media.medialists.info.dialog.title.label']}</dt>
<dd>#{list.title}</dd>
<dt>#{CmsDefaultStepsMessageBundle['media.medialists.info.dialog.description.label']}</dt>
<dd>#{list.description}</dd>
</dl>
</div>
<div class="modal-footer">
<button class="btn btn-secondary"
data-dismiss="modal"
type="button">
#{CmsDefaultStepsMessageBundle['media.medialists.info.dialog.close']}
</button>
</div>
</div>
</div>
</div>
<a class="btn btn-primary mx-2"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{list.name}/@details">
<bootstrap:svgIcon icon="pen" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.edit.button']}"</span>
</a>
<librecms:assetPickerButton
assetPickerId="attach-media-picker-#{list.uuid}"
buttonIcon="file-earmark-plus"
buttonText="#{CmsDefaultStepsMessageBundle['media.medialists.media.add.label']}"
/>
<libreccm:deleteDialog
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{list.name}/@remove"
buttonLabelClass="sr-only"
buttonText="#{CmsDefaultStepsMessageBundle['media.medialists.remove.label']}"
buttonTextClass="ml-2"
cancelLabel="#{CmsDefaultStepsMessageBundle['media.medialists.remove.cancel']}"
confirmLabel="#{CmsDefaultStepsMessageBundle['media.medialists.remove.confirm']}"
dialogId="medialist-delete-#{list.uuid}"
dialogTitle="#{CmsDefaultStepsMessageBundle['media.medialists.remove.title']}"
message="#{CmsDefaultStepsMessageBundle.getMessage('media.medialists.remove.message', [list.name])}"
/>
<librecms:assetPicker
actionUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{list.name}/media/@create"
assetType="#{CmsMediaStep.audioAssetType},#{CmsMediaStep.externalAudioAssetType},#{CmsMediaStep.externalVideoAssetType},#{CmsMediaStep.imageType},#{CmsMediaStep.videoAssetType}"
assetPickerId="attach-media-picker-#{list.uuid}"
baseUrl="#{CmsMediaStep.mediaAssetPickerBaseUrl}"
contentSection="#{CmsMediaStep.sectionName}"
formParamName="assetIdentifier"
/>
</div>
</div>
<ul class="cms-medias mt-3 list-group"
data-list-uuid="#{list.uuid}">
<c:forEach items="#{list.media}"
var="media">
<li class="cms-media list-group-item mb-3 d-flex justify-content-between"
data-id="#{media.uuid}">
<div>
<c:choose>
<c:when test="#{media.assetType.equals(CmsMediaStep.audioAssetType)}">
<bootstrap:svgIcon icon="file-music" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.mediatype.audioasset']}</span>
</c:when>
<c:when test="#{media.assetType.equals(CmsMediaStep.externalAudioAssetType)}">
<bootstrap:svgIcon icon="link-45deg" />
<bootstrap:svgIcon icon="file-music" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.mediatype.externalaudioasset']}</span>
</c:when>
<c:when test="#{media.assetType.equals(CmsMediaStep.externalVideoAssetType)}">
<bootstrap:svgIcon icon="link-45deg" />
<bootstrap:svgIcon icon="film" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.mediatype.externalvideoasset']}</span>
</c:when>
<c:when test="#{media.assetType.equals(CmsMediaStep.imageType)}">
<bootstrap:svgIcon icon="image" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.mediatype.image']}</span>
</c:when>
<c:when test="#{media.assetType.equals(CmsMediaStep.videoAssetType)}">
<bootstrap:svgIcon icon="film" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.mediatype.video']}</span>
</c:when>
</c:choose>
<span class="cms-media-label">#{media.title}</span>
</div>
<div class="cms-media-buttons d-flex">
<button class="btn btn-secondary cms-sort-handle mr-2"
type="button">
<bootstrap:svgIcon icon="arrows-move" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.media.move.button']}"</span>
</button>
<button class="btn btn-secondary mx-2"
data-toggle="modal"
data-target="#media-#{media.uuid}-info-dialog"
type="button">
<bootstrap:svgIcon icon="info-circle" />
<span class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.media.info.button']}"</span>
</button>
<div aria-hidden="true"
aria-labelledby="media-#{media.uuid}-info-dialog-title"
class="modal fade"
id="media-#{media.uuid}-info-dialog"
tabindex="-1"
>
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title"
id="media-#{media.uuid}-info-dialog-title">
#{CmsDefaultStepsMessageBundle.getMessage('media.medialists.media.info.dialog.title', [list.name, media.title])}
</h3>
<button
aria-label="#{CmsDefaultStepsMessageBundle['media.medialists.media.info.dialog.close']}"
class="close"
data-dismiss="modal"
type="button">
<bootstrap:svgIcon icon="x" />
</button>
</div>
<div class="modal-body">
<dl>
<dt>#{CmsDefaultStepsMessageBundle['media.medialists.media.info.dialog.title.label']}</dt>
<dd>#{media.title}</dd>
<dt>#{CmsDefaultStepsMessageBundle['media.medialists.media.info.dialog.type.label']}</dt>
<dd>#{media.assetTypeLabel}</dd>
</dl>
</div>
<div class="modal-footer">
<button class="btn btn-secondary"
data-dismiss="modal"
type="button">
#{CmsDefaultStepsMessageBundle['media.medialists.media.info.dialog.close']}
</button>
</div>
</div>
</div>
</div>
<libreccm:deleteDialog
actionTarget="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@media/medialists/#{list.name}/media/#{media.uuid}/@remove"
buttonLabelClass="sr-only"
buttonText="#{CmsDefaultStepsMessageBundle['media.medialists.media.remove.label']}"
buttonTextClass="ml-2"
cancelLabel="#{CmsDefaultStepsMessageBundle['media.medialists.media.remove.cancel']}"
confirmLabel="#{CmsDefaultStepsMessageBundle['media.medialists.media.remove.confirm']}"
dialogId="media-delete-#{media.uuid}"
dialogTitle="#{CmsDefaultStepsMessageBundle['media.medialists.media.remove.title']}"
message="#{CmsDefaultStepsMessageBundle.getMessage('media.medialists.media.remove.message', [list.name, media.title])}"
/>
</div>
</li>
</c:forEach>
</ul>
</li>
</c:forEach>
</ul>
<div>
<button class="btn btn-secondary media-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 class="sr-only">#{CmsDefaultStepsMessageBundle['media.medialists.order.save.inprogress']}</span>
</span>
<span>#{CmsDefaultStepsMessageBundle['media.medialists.order.save']}</span>
</button>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -0,0 +1,37 @@
<!DOCTYPE html [<!ENTITY times '&#215;'>]>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:bootstrap="http://xmlns.jcp.org/jsf/composite/components/bootstrap"
xmlns:c="http://xmlns.jcp.org/jsp/jstl/core"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets">
<ui:composition template="/WEB-INF/views/org/librecms/ui/contentsection/documents/document.xhtml">
<ui:param name="activePage" value="document" />
<ui:param name="title" value="#{CmsDefaultStepsMessageBundle['media.medialist.not_found.title']}" />
<ui:define name="breadcrumb">
<ui:include src="document-breadcrumbs.xhtml" />
<li aria-current="page" class="breadcrumb-item">
#{CmsAdminMessages['contentsection.document.media.breadcrumb']}
</li>
</ui:define>
<ui:define name="main">
<div class="container">
<div class="alert alert-danger" role="alert">
#{CmsDefaultStepsMessageBundle.getMessage('media.medialist.not_found.message', [contentItem, listIdentifier])}
</div>
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -38,7 +38,7 @@
method="post"> method="post">
<div class="modal-header"> <div class="modal-header">
<h3 class="modal-title" <h3 class="modal-title"
id="add-attachment.ist-dialog-title">#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.add.dialog.title']}</h3> id="add-attachment-list-dialog-title">#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.add.dialog.title']}</h3>
<button aria-label="#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.add.dialog.close']}" <button aria-label="#{CmsDefaultStepsMessageBundle['relatedinfo.attachmentlists.add.dialog.close']}"
class="close" class="close"
data-dismiss="modal" data-dismiss="modal"
@ -85,7 +85,7 @@
</div> </div>
<div> <div>
<button class="btn btn-secondary save-order-button" <button class="btn btn-secondary attachments-save-order-button"
disabled="disabled" disabled="disabled"
type="button"> type="button">
<span class="save-icon"> <span class="save-icon">
@ -298,7 +298,7 @@
</ul> </ul>
<div> <div>
<button class="btn btn-secondary save-order-button" <button class="btn btn-secondary attachments-save-order-button"
disabled="disabled" disabled="disabled"
type="button"> type="button">
<span class="save-icon"> <span class="save-icon">

View File

@ -240,3 +240,98 @@ relatedinfo.attachments.info.dialog.title.label=Title
relatedinfo.attachments.info.dialog.type.label=Type relatedinfo.attachments.info.dialog.type.label=Type
relatedinfo.attachmentlists.order.save.inprogress=Saving... relatedinfo.attachmentlists.order.save.inprogress=Saving...
categorization.title=Categories assigned to content item {0} categorization.title=Categories assigned to content item {0}
media.sortmedia.errors.general=Unexpected error. Failed to sort media.
media.sortmedia.errors.save=Failed to save order.
media.medialists.add.button.label=Add media list
media.medialists.add.dialog.title=Add new media list
contentsection.documents.media.medialist.back=Back
media.medialists.add.dialog.close=Close
media.medialists.add.dialog.name.help=The name of the new media list. May only contain the letters A to Z, a to z, number, the dash ("-") and the underscore ("_").
media.medialists.add.dialog.name.label=Name
media.medialists.add.dialog.title.help=The title of the new media list.
media.medialists.add.dialog.title.label=Title
media.medialists.add.dialog.description.help=A short description of the new media list (optional).
media.medialists.add.dialog.description.label=Description
media.medialists.add.dialog.add_list=Add media list
media.medialists.order.save.inprogress=Saving media order...
media.medialists.order.save=Save order
media.medialists.move.button=Move media list
media.medialists.info.button=Show media list details
media.medialists.info.dialog.title=Media List {0} Details
media.medialists.info.dialog.close=Close
media.medialists.info.dialog.title.label=Titel
media.medialists.info.dialog.description.label=Description
media.medialists.edit.button=Edit media list
media.medialists.media.add.label=Add media
media.medialists.remove.label=Remove media list
media.medialists.remove.cancel=Cancel
media.medialists.remove.title=Confirm removal of media list
media.medialists.remove.message=Are you sure to remove the media list {0}?
media.medialists.mediatype.audioasset=Audio
media.medialists.mediatype.externalaudioasset=External audio file
media.medialists.mediatype.externalvideoasset=External Video
media.medialists.mediatype.image=Image
media.medialists.mediatype.video=Video
media.medialists.media.move.button=Move media
media.medialists.media.info.button=Media Details
media.medialists.media.info.dialog.title=Details of media {1} of media list {0}
media.medialists.media.info.dialog.close=Close
media.medialists.media.info.dialog.title.label=Title
media.medialists.media.info.dialog.type.label=Type
media.medialists.media.remove.label=Remove media
media.medialists.media.remove.cancel=Cancel
media.medialists.media.remove.confirm=Remove media
media.medialists.media.remove.title=Confirm media removal
media.medialists.media.remove.message=Are you sure to remove media {1} from media list {0}?
media.medialist.details.title=Details Media List {0}
media.medialist.details.name.label=Name
media.medialist.details.name.edit=Edit name of media list
media.medialist.details.name_edit_dialog.title=Edit name of media list{0}
media.medialist.details.name_edit_dialog.close=Cancel
media.medialist.details.name_edit_dialog.name.help=The name of the media list. May only contain the letters A to Z, a to z, number, the dash ("-") and the underscore ("_").
media.medialist.details.name_edit_dialog.name.label=Name
media.medialist.details.name_edit_dialog.save=Save
media.medialist.details.title.add_button.label=Add localized title
media.medialist.details.title.add.cancel=Cancel
media.medialist.details.title.add.locale.help=The locale of the localized title.
media.medialist.details.title.add.locale.label=Locale
media.medialist.details.title.add.submit=Add localized title
media.medialist.details.title.add.title=Add localized title
media.medialist.details.title.add.value.help=The localized title of the media list.
media.medialist.details.title.add.value.label=Title
media.medialist.details.title.edit_button.label=Edit
media.medialist.details.title.edit.cancel=Cancel
media.medialist.details.title.edit.submit=Save
media.medialist.details.title.edit.title=Edit localized title of media list
media.medialist.details.title.edit.value.help=The localized title of the media list.
media.medialist.details.title.remove_button.label=Remove localized title
media.medialist.details.title.remove.cancel=Cancel
media.medialist.details.title.remove.submit=Remove localized title
media.medialist.details.title.remove.text=Are you sure to remove the following localized title:
media.medialist.details.title.remove.title=Confirm removal of localized title
media.medialist.details.title_editor.title=Title
media.medialist.details.description.add_button.label=Add localized description
media.medialist.details.description.add.cancel=Cancel
media.medialist.details.description.add.locale.help=The locale of the localized description.
media.medialist.details.description.add.locale.label=Locale
media.medialist.details.description.add.submit=Add localized description
media.medialist.details.description.add.title=Add localized description
media.medialist.details.description.add.value.help=The localized description.
media.medialist.details.description.add.value.label=Description
media.medialist.details.description.edit_button.label=Edit localized description
media.medialist.details.description.edit.cancel=Cancel
media.medialist.details.description.edit.submit=Save
media.medialist.details.description.edit.title=Edit localized description
media.medialist.details.description.edit.value.help=The localized description.
media.medialist.details.description.edit.value.label=Description
media.medialist.details.description.remove_button.label=Remove localized description
media.medialist.details.description.remove.cancel=Cancel
media.medialist.details.description.remove.submit=Remove
media.medialist.details.description.remove.text=Are your sure to remove the following localized description:
media.medialist.details.description.remove.title=Confirm removal of localized description
media.medialist.details.description_editor.title=Description
media.medialists.media.not_found.title=Media not found
contentsection.document.media.breadcrumb=Media
media.medialists.media.not_found.message=No media identified by {1} found in content section {0}.
media.medialist.not_found.title=Media List not found
media.medialist.not_found.message=Content Item {0} has not media list {1}.

View File

@ -240,3 +240,98 @@ relatedinfo.attachments.info.dialog.title.label=Titel
relatedinfo.attachments.info.dialog.type.label=Typ relatedinfo.attachments.info.dialog.type.label=Typ
relatedinfo.attachmentlists.order.save.inprogress=Speichere... relatedinfo.attachmentlists.order.save.inprogress=Speichere...
categorization.title=Zugeordnete Kategorien Dokument {0} categorization.title=Zugeordnete Kategorien Dokument {0}
media.sortmedia.errors.general=Unerwarteter Fehler. Sortieren der Medien nicht m\u00f6glich.
media.sortmedia.errors.save=Speichern der Sortierung fehlgeschlagen.
media.medialists.add.button.label=Medienliste hinzuf\u00fcgen
media.medialists.add.dialog.title=Neue Medienliste hinzuf\u00fcgen
contentsection.documents.media.medialist.back=Zur\u00fcck
media.medialists.add.dialog.close=Cancel
media.medialists.add.dialog.name.help=Der Name der neuen Medienliste. Darf nur die Buchstaben a bis z, A bis Z, Zahlen, den Bindestrich ("-") und den Unterstrich ("_") enthalten.
media.medialists.add.dialog.name.label=Name
media.medialists.add.dialog.title.help=Der Titel der neuen Medienliste.
media.medialists.add.dialog.title.label=Title
media.medialists.add.dialog.description.help=Eine kurze Beschreibung der neuen Medienliste (optional).
media.medialists.add.dialog.description.label=Beschreibung
media.medialists.add.dialog.add_list=Medienliste hinzuf\u00fcgen
media.medialists.order.save.inprogress=Speichere Sortierung der Medien...
media.medialists.order.save=Sortierung speichern
media.medialists.move.button=Medienliste verschieben
media.medialists.info.button=Details zur Medienliste anzeigen
media.medialists.info.dialog.title=Medien Liste {0} Details
media.medialists.info.dialog.close=Schlie\u00dfen
media.medialists.info.dialog.title.label=Titel
media.medialists.info.dialog.description.label=Beschreibung
media.medialists.edit.button=Medienliste bearbeiten
media.medialists.media.add.label=Medium hinzuf\u00fcgen
media.medialists.remove.label=Medienliste l\u00f6schen
media.medialists.remove.cancel=Abbrechen
media.medialists.remove.title=L\u00f6schen der Medienliste best\u00e4tigen
media.medialists.remove.message=Sind Sie sicher, dass Sie die Medienliste {0} l\u00f6schen wollen?
media.medialists.mediatype.audioasset=Audio
media.medialists.mediatype.externalaudioasset=Externe audio Datei
media.medialists.mediatype.externalvideoasset=Externes Video
media.medialists.mediatype.image=Bild
media.medialists.mediatype.video=Video
media.medialists.media.move.button=Medium verschieben
media.medialists.media.info.button=Medium Details
media.medialists.media.info.dialog.title=Details Medium {1} aus Medienliste {0}
media.medialists.media.info.dialog.close=Schlie\u00dfen
media.medialists.media.info.dialog.title.label=Titel
media.medialists.media.info.dialog.type.label=Typ
media.medialists.media.remove.label=Medium entfernen
media.medialists.media.remove.cancel=Abbrechen
media.medialists.media.remove.confirm=Medium entfernen
media.medialists.media.remove.title=Entfernen eines Mediums best\u00e4tigen
media.medialists.media.remove.message=Sind Sie sicher, dass Sie das Medium {1} aus der Medienliste {0} entfernen wollen?
media.medialist.details.title=Details Medien Liste {0}
media.medialist.details.name.label=Name
media.medialist.details.name.edit=Name der Medienliste bearbeiten
media.medialist.details.name_edit_dialog.title=Name der Medienliste {0} bearbeiten
media.medialist.details.name_edit_dialog.close=Abbrechen
media.medialist.details.name_edit_dialog.name.help=Der Name der Medienliste. Darf nur die Buchstaben a bis z, A bis Z, Zahlen, den Bindestrich ("-") und den Unterstrich ("_") enthalten.
media.medialist.details.name_edit_dialog.name.label=Name
media.medialist.details.name_edit_dialog.save=Speichern
media.medialist.details.title.add_button.label=Lokalisierten Titel hinzuf\u00fcgen
media.medialist.details.title.add.cancel=Abbrechen
media.medialist.details.title.add.locale.help=Die Sprache des lokalisierten Titels.
media.medialist.details.title.add.locale.label=Sprache
media.medialist.details.title.add.submit=Lokalisierten Titel hinzuf\u00fcgen
media.medialist.details.title.add.title=Lokalisierten Titel hinzuf\u00fcgen
media.medialist.details.title.add.value.help=Der lokalisierte Titel der Medienliste.
media.medialist.details.title.add.value.label=Titel
media.medialist.details.title.edit_button.label=Bearbeiten
media.medialist.details.title.edit.cancel=Abbrechen
media.medialist.details.title.edit.submit=Speichern
media.medialist.details.title.edit.title=Lokalisierten Titel der Medienliste bearbeiten
media.medialist.details.title.edit.value.help=Der lokalisierte Titel der Medienliste.
media.medialist.details.title.remove_button.label=Lokalisierten Titel entfernen
media.medialist.details.title.remove.cancel=Abbrechen
media.medialist.details.title.remove.submit=Lokalisierten Titel entfernen
media.medialist.details.title.remove.text=Sind Sie sicher, dass Sie den folgenden lokalisierten Titel entfernen wollen:
media.medialist.details.title.remove.title=Entfernen eines lokalisierten Titels best\u00e4tigen
media.medialist.details.title_editor.title=Titel
media.medialist.details.description.add_button.label=Lokalisierte Beschreibung hinzuf\u00fcgen
media.medialist.details.description.add.cancel=Abbrechen
media.medialist.details.description.add.locale.help=Die Sprache der lokaliserten Beschreibung.
media.medialist.details.description.add.locale.label=Beschreibung
media.medialist.details.description.add.submit=Lokalisierte Beschreibung hinzuf\u00fcgen
media.medialist.details.description.add.title=Lokalisierte Beschreibung hinzuf\u00fcgen
media.medialist.details.description.add.value.help=Die lokalisierte Beschreibung.
media.medialist.details.description.add.value.label=Beschreibung
media.medialist.details.description.edit_button.label=Lokalisierte Beschreibung bearbeiten
media.medialist.details.description.edit.cancel=Abbrechen
media.medialist.details.description.edit.submit=Speichern
media.medialist.details.description.edit.title=Lokalisierte Beschreibung bearbeiten
media.medialist.details.description.edit.value.help=Die lokalisierte Beschreibung.
media.medialist.details.description.edit.value.label=Beschreibung
media.medialist.details.description.remove_button.label=Lokalisierte Beschreibung entfernen
media.medialist.details.description.remove.cancel=Abbrechen
media.medialist.details.description.remove.submit=Entfernen
media.medialist.details.description.remove.text=Sind Sie sicher, dass Sie die folgende lokalisierte Beschreibung entfernen wollen:
media.medialist.details.description.remove.title=Entfernen einer lokalisierten Beschreibung best\u00e4tigen
media.medialist.details.description_editor.title=Beschreibung
media.medialists.media.not_found.title=Medium nicht gefunden
contentsection.document.media.breadcrumb=Medien
media.medialists.media.not_found.message=Kein Medium mit UUID {1} in Content Section {0} gefunden.
media.medialist.not_found.title=Medienliste nicht gefunden
media.medialist.not_found.message=Keine Medienliste {1} f\u00fcr Dokument {0} gefunden.

View File

@ -6,4 +6,6 @@ import "./cms-attachment-lists";
import "./cms-contentitempicker"; import "./cms-contentitempicker";
import "./cms-media-lists";
import "./cms-related-link"; import "./cms-related-link";

View File

@ -1,4 +1,3 @@
// import Sortable = require("sortablejs")
import Sortable, { SortableEvent } from "sortablejs"; import Sortable, { SortableEvent } from "sortablejs";
interface RelatedInfoStepAttachmentOrder { interface RelatedInfoStepAttachmentOrder {
@ -37,7 +36,9 @@ document.addEventListener("DOMContentLoaded", function (event) {
initAttachments(attachments[i] as HTMLElement); initAttachments(attachments[i] as HTMLElement);
} }
const saveOrderButtons = document.querySelectorAll(".save-order-button"); const saveOrderButtons = document.querySelectorAll(
".attachments-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) { for (let i = 0; i < saveOrderButtons.length; i++) {
saveOrderButtons[i].addEventListener("click", saveOrder); saveOrderButtons[i].addEventListener("click", saveOrder);
} }
@ -72,7 +73,9 @@ function initAttachments(attachments: HTMLElement): Sortable {
} }
function enableSaveButton(event: SortableEvent) { function enableSaveButton(event: SortableEvent) {
const saveOrderButtons = document.querySelectorAll(".save-order-button"); const saveOrderButtons = document.querySelectorAll(
".attachments-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) { for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[ const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i i
@ -136,7 +139,7 @@ function saveOrder() {
attachmentsSortables[key].toArray(); attachmentsSortables[key].toArray();
} }
console.dir(attachmentOrder); // console.dir(attachmentOrder);
const cmsAttachments = document.querySelector(".cms-attachment-lists"); const cmsAttachments = document.querySelector(".cms-attachment-lists");
if (!cmsAttachments) { if (!cmsAttachments) {
showGeneralError(); showGeneralError();
@ -150,9 +153,11 @@ function saveOrder() {
); );
} }
const saveOrderButtons = document.querySelectorAll(".save-order-button"); const saveOrderButtons = document.querySelectorAll(".attachments-save-order-button");
for (let i = 0; i < saveOrderButtons.length; i++) { for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[i] as HTMLButtonElement; const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
saveOrderButton.disabled = true; saveOrderButton.disabled = true;
const saveIcon = saveOrderButton.querySelector(".save-icon"); const saveIcon = saveOrderButton.querySelector(".save-icon");
const spinner = saveOrderButton.querySelector(".save-spinner"); const spinner = saveOrderButton.querySelector(".save-spinner");
@ -177,8 +182,10 @@ function saveOrder() {
i i
] as HTMLButtonElement; ] as HTMLButtonElement;
// saveOrderButton.disabled = true; // saveOrderButton.disabled = true;
const saveIcon = saveOrderButton.querySelector(".save-icon"); const saveIcon =
const spinner = saveOrderButton.querySelector(".save-spinner"); saveOrderButton.querySelector(".save-icon");
const spinner =
saveOrderButton.querySelector(".save-spinner");
saveIcon?.classList.toggle("d-none"); saveIcon?.classList.toggle("d-none");
spinner?.classList.toggle("d-none"); spinner?.classList.toggle("d-none");
} }
@ -189,8 +196,10 @@ function saveOrder() {
i i
] as HTMLButtonElement; ] as HTMLButtonElement;
saveOrderButton.disabled = false; saveOrderButton.disabled = false;
const saveIcon = saveOrderButton.querySelector(".save-icon"); const saveIcon =
const spinner = saveOrderButton.querySelector(".save-spinner"); saveOrderButton.querySelector(".save-icon");
const spinner =
saveOrderButton.querySelector(".save-spinner");
saveIcon?.classList.toggle("d-none"); saveIcon?.classList.toggle("d-none");
spinner?.classList.toggle("d-none"); spinner?.classList.toggle("d-none");
} }

View File

@ -0,0 +1,239 @@
import Sortable, { SortableEvent } from "sortablejs";
interface MediaStepMediaOrder {
mediaListsOrder: string[];
mediaOrder: {
[key: string]: string[];
};
movedMedia: MovedMedia[];
}
interface MovedMedia {
mediaUuid: string;
fromListUuid: string;
toListUuid: string;
}
const movedMedia: MovedMedia[] = [];
let mediaListSortable: Sortable;
let mediaSortables: {
[key: string]: Sortable;
} = {};
document.addEventListener("DOMContentLoaded", function (event) {
const mediaLists = document.querySelector(".cms.media-lists");
if (mediaLists) {
mediaListSortable = initMediaLists(mediaLists as HTMLElement);
}
const medias = document.querySelectorAll(".cms-medias");
for (let i = 0; i < medias.length; i++) {
initMedias(medias[i] as HTMLElement);
}
const saveOrderButtons = document.querySelectorAll(
".media-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) {
saveOrderButtons[i].addEventListener("click", saveOrder);
}
});
function initMediaLists(mediaList: HTMLElement): Sortable {
return new Sortable(mediaList, {
animation: 150,
group: "cms-media-lists",
handle: ".cms-sort-handle",
onEnd: enableSaveButton
});
}
function initMedias(medias: HTMLElement): Sortable {
const sortable = new Sortable(medias, {
animation: 150,
group: "cms-media",
handle: ".cms-sort-handle",
onEnd: moveMedia
});
const listUuid = medias.getAttribute("data-list-uuid");
if (listUuid === null) {
showGeneralError();
throw Error("medias without data-list-uuid attribute found.");
}
mediaSortables[listUuid] = sortable;
return sortable;
}
function enableSaveButton(event: SortableEvent) {
const saveOrderButtons = document.querySelectorAll(
".media-save-order-button"
);
for (let i = 0; i < saveOrderButtons.length; i++) {
const saveOrderButton: HTMLButtonElement = saveOrderButtons[
i
] as HTMLButtonElement;
saveOrderButton.disabled = false;
}
}
function moveMedia(event: SortableEvent) {
const fromListUuid = event.from.getAttribute("data-list-uuid");
if (!fromListUuid) {
showGeneralError();
throw Error(
"A media was moved, but the list from which the media was removed has no data-id attribute."
);
}
const toListUuid = event.to.getAttribute("data-list-uuid");
if (!toListUuid) {
showGeneralError();
throw Error(
"An media was moved, but the list to which the media was removed has no data-id attribute."
);
}
if (fromListUuid !== toListUuid) {
const mediaUuid = event.item.getAttribute("data-id");
if (!mediaUuid) {
showGeneralError();
throw Error(
"An media was moved, but the media was removed has no dat-id attribute."
);
}
const moved: MovedMedia = {
fromListUuid,
toListUuid,
mediaUuid: mediaUuid
};
movedMedia.push(moved);
}
enableSaveButton(event);
}
function saveOrder() {
const mediaOrder: MediaStepMediaOrder = {
mediaListsOrder: mediaListSortable.toArray(),
mediaOrder: {},
movedMedia
};
for (let key in mediaSortables) {
mediaOrder.mediaOrder[key] =
mediaSortables[key].toArray();
}
// console.dir(mediaOrder);
const cmsMedia = document.querySelector(".cms-media-lists");
if (!cmsMedia) {
showGeneralError();
throw Error("cms-media-lists container not found.");
}
const baseUrl = cmsMedia.getAttribute("data-baseUrl");
if (!baseUrl) {
showGeneralError();
throw Error(
"data-baseUrl attribute on cms-media-lists container is missing or empty."
);
}
const saveOrderButtons = document.querySelectorAll(".media-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(baseUrl, {
credentials: "include",
body: JSON.stringify(mediaOrder),
headers,
method: "POST"
})
.then(response => {
if (response.ok) {
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");
}
} 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 media 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 media order: ${error}`);
});
}
function showGeneralError(): void {
const alertTemplate = document.querySelector(
"#cms-sort-media-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(
"#cms-sort-media-error-save"
) as HTMLTemplateElement;
const alert = alertTemplate.content.cloneNode(true) as Element;
const container = document.querySelector("#messages");
if (container) {
container.appendChild(alert);
}
}