Bugfixes for the edit steps of the multipart article

pull/10/head
Jens Pelzetter 2021-12-24 11:43:52 +01:00
parent 568a9fa6bc
commit 4d03ef9ec2
12 changed files with 269 additions and 28 deletions

View File

@ -25,6 +25,7 @@ import org.librecms.ui.contentsections.documents.relatedinfo.RelatedInfoStepServ
import org.librecms.ui.contenttypes.article.MvcArticlePropertiesStep;
import org.librecms.ui.contenttypes.article.MvcArticleTextBodyStep;
import org.librecms.ui.contenttypes.article.MvcArticleTextBodyStepResources;
import org.librecms.ui.contenttypes.mpa.MpaSectionsResources;
import org.librecms.ui.contenttypes.mpa.MvcMpaPropertiesStep;
import org.librecms.ui.contenttypes.mpa.MvcMpaSectionsStep;
@ -59,6 +60,7 @@ public class CmsMvcAuthoringSteps implements MvcAuthoringSteps {
return Set.of(
MediaStepService.class,
MvcArticleTextBodyStepResources.class,
MpaSectionsResources.class,
RelatedInfoStepService.class
);
}

View File

@ -38,9 +38,9 @@ import javax.inject.Named;
public class MpaSectionModel {
private String articleTitle;
private long sectionId;
private String sectionTitle;
private boolean pageBreak;
@ -53,16 +53,18 @@ public class MpaSectionModel {
private List<String> unusedTitleLocales;
private List<CmsEditorLocaleVariantRow> textValues;
private List<CmsEditorLocaleVariantRow> textVariants;
private Map<String, String> textValues;
private Map<String, String> truncatedTextValues;
private List<String> unusedTextLocales;
public String getArticleTitle() {
return articleTitle;
}
protected void setArticleTitle(final String articleTitle) {
this.articleTitle = articleTitle;
}
@ -74,11 +76,11 @@ public class MpaSectionModel {
protected void setSectionId(final long sectionId) {
this.sectionId = sectionId;
}
public String getSectionTitle() {
return sectionTitle;
}
protected void setSectionTitle(final String sectionTitle) {
this.sectionTitle = sectionTitle;
}
@ -126,13 +128,22 @@ public class MpaSectionModel {
public boolean getHasUnusedTitleLocales() {
return !unusedTitleLocales.isEmpty();
}
public List<CmsEditorLocaleVariantRow> getTextValues() {
return Collections.unmodifiableList(textValues);
public List<CmsEditorLocaleVariantRow> getTextVariants() {
return Collections.unmodifiableList(textVariants);
}
protected void setTextValues(final List<CmsEditorLocaleVariantRow> textValues) {
this.textValues = new ArrayList<>(textValues);
protected void setTextVariants(
final List<CmsEditorLocaleVariantRow> textVariants) {
this.textVariants = new ArrayList<>(textVariants);
}
public Map<String, String> getTextValues() {
return Collections.unmodifiableMap(textValues);
}
protected void setTextValues(final Map<String, String> textValues) {
this.textValues = new HashMap<>(textValues);
}
public Map<String, String> getTruncatedTextValues() {
@ -148,7 +159,7 @@ public class MpaSectionModel {
public List<String> getUnusedTextLocales() {
return Collections.unmodifiableList(unusedTextLocales);
}
public boolean getHasUnusedTextLocales() {
return !unusedTextLocales.isEmpty();
}

View File

@ -0,0 +1,109 @@
/*
* 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.contenttypes.mpa;
import org.librecms.contentsection.ContentItem;
import org.librecms.contentsection.ContentItemRepository;
import org.librecms.contentsection.ContentSection;
import org.librecms.contenttypes.MultiPartArticle;
import org.librecms.ui.contentsections.ContentSectionsUi;
import org.librecms.ui.contentsections.ItemPermissionChecker;
import org.librecms.ui.contentsections.documents.MvcAuthoringSteps;
import java.util.Locale;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.transaction.Transactional;
import javax.ws.rs.ForbiddenException;
import javax.ws.rs.GET;
import javax.ws.rs.NotFoundException;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
@RequestScoped
@Path(MvcAuthoringSteps.PATH_PREFIX + "mpa-sections-resources")
public class MpaSectionsResources {
@Inject
private ContentSectionsUi sectionsUi;
@Inject
private ItemPermissionChecker itemPermissionChecker;
@Inject
private ContentItemRepository itemRepo;
@GET
@Path("/{sectionId}/text/@variant/{locale}")
@Produces(MediaType.TEXT_HTML)
@Transactional(Transactional.TxType.REQUIRED)
public String getTextValue(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPathParam,
@PathParam("sectionId")
final String sectionIdParam,
@PathParam("locale")
final String localeParam
) {
final ContentSection contentSection = sectionsUi
.findContentSection(sectionIdentifier)
.orElseThrow(
() -> new NotFoundException()
);
final ContentItem document = itemRepo
.findByPath(contentSection, documentPathParam)
.orElseThrow(
() -> new NotFoundException()
);
if (!(document instanceof MultiPartArticle)) {
throw new NotFoundException();
}
final MultiPartArticle mpa = (MultiPartArticle) document;
if (itemPermissionChecker.canEditItem(mpa)) {
if (!sectionIdParam.matches("[0-9]*")) {
throw new NotFoundException();
}
final long sectionId = Long.parseLong(sectionIdParam);
return mpa
.getSections()
.stream()
.filter(sec -> sec.getSectionId() == sectionId)
.findAny()
.map(sec -> sec.getText().getValue(new Locale(localeParam)))
.orElseThrow(() -> new NotFoundException());
} else {
throw new ForbiddenException();
}
}
}

View File

@ -93,7 +93,6 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
@Inject
private MpaSectionsStepModel mpaSectionsStepModel;
@Inject
private MpaSectionModel mpaSectionModel;
@ -459,6 +458,29 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
}
}
@GET
@Path("/{sectionId}/text/@view/{locale}")
@Transactional(Transactional.TxType.REQUIRED)
public String viewTextValue(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
final String sectionIdentifier,
@PathParam(MvcAuthoringSteps.DOCUMENT_PATH_PATH_PARAM_NAME)
final String documentPath,
@PathParam("sectionId")
final String sectionIdParam,
@PathParam("locale")
final String localeParam
) {
mpaSectionModel.setSelectedLocale(localeParam);
return initSectionModel(
sectionIdentifier,
documentPath,
sectionIdParam,
"org/librecms/ui/contenttypes/mpa/mpa-section-view-text.xhtml"
);
}
@GET
@Path("/{sectionId}/text/@edit/{locale}")
@Transactional(Transactional.TxType.REQUIRED)
@ -478,7 +500,7 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
sectionIdentifier,
documentPath,
sectionIdParam,
"org/librecms/ui/contenttypes/mpa/mpa-section-text.xhtml"
"org/librecms/ui/contenttypes/mpa/mpa-section-edit-text.xhtml"
);
}
@ -534,7 +556,7 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
}
@POST
@Path("/{sectionId}/text/@remove")
@Path("/{sectionId}/text/@remove/{locale}")
@Transactional(Transactional.TxType.REQUIRED)
public String removeTextValue(
@PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM)
@ -543,7 +565,7 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
final String documentPath,
@PathParam("sectionId")
final String sectionIdParam,
@FormParam("locale")
@PathParam("locale")
final String localeParam
) {
try {
@ -738,7 +760,7 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
section.getTitle()
)
);
mpaSectionModel.setTextValues(
mpaSectionModel.setTextVariants(
section
.getText()
.getValues()
@ -760,6 +782,20 @@ public class MvcMpaSectionsStep extends AbstractMvcAuthoringStep {
)
)
);
mpaSectionModel
.setTextValues(
section
.getText()
.getValues()
.entrySet()
.stream()
.collect(
Collectors.toMap(
entry -> entry.getKey().toString(),
Map.Entry::getValue
)
)
);
mpaSectionModel
.setTruncatedTextValues(
section

View File

@ -15,6 +15,7 @@
<span class="sr-only">#{CmsMpaMessageBundle['sectionstep.textstep.back']}</span>
</a>
<h2>#{CmsMpaMessageBundle.getMessage('sectionstep.textstep.header.edit',[CmsMpaSectionStep.articleTitle, CmsMpaSectionStep.titleValues.get(CmsMpaSectionStep.selectedLocale) , CmsMpaSectionStep.selectedLocale])}</h2>
</div>
<c:if test="#{CmsMpaSectionsStep.canEdit}">
<librecms:cmsEditor
@ -22,20 +23,18 @@
baseUrl="#{mvc.basePath}"
canEdit="#{CmsMpaSectionsStep.canEdit}"
contentSection="#{ContentSectionModel.sectionName}"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/edit"
editMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}/text/@edit"
editorId="cms-mpa-section-text-editor"
objectIdentifier="#{CmsSelectedDocumentModel.itemPath}"
selectedLocale="#{CmsMpaSectionStep.selectedLocale}"
title="#{CmsMpaMessageBundle['sectionstep.textstep.text.editor.header']}"
variantUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/variants"
variantUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections-resources/#{CmsMpaSectionStep.sectionId}/text/@variant"
/>
</c:if>
</div>
</ui:define>
<ui:define name="scripts">
<script src="#{request.contextPath}/assets/@content-sections/article-text-step.js"></script>
<script src="#{request.contextPath}/assets/@content-sections/mpa-section-edit-text.js"></script>
</ui:define>
</ui:composition>

View File

@ -0,0 +1,28 @@
<!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:h="http://xmlns.jcp.org/jsf/html"
xmlns:libreccm="http://xmlns.jcp.org/jsf/composite/components/libreccm"
xmlns:librecms="http://xmlns.jcp.org/jsf/composite/components/librecms"
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">
<a class="btn btn-secondary btn-sm mr-2"
href="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}">
<bootstrap:svgIcon icon="caret-left-fill" />
<span class="sr-only">#{CmsMpaMessageBundle['sectionstep.textstep.back']}</span>
</a>
<h2>#{CmsMpaMessageBundle.getMessage('sectionstep.textstep.header.view',[CmsMpaSectionStep.articleTitle, CmsMpaSectionStep.titleValues.get(CmsMpaSectionStep.selectedLocale) , CmsMpaSectionStep.selectedLocale])}</h2>
</div>
<div class="cms-text-preview article-text border p-2">
<h:outputText escape="false"
value="#{CmsMpaSectionStep.textValues.get(CmsMpaSectionStep.selectedLocale)}" />
</div>
</ui:define>
</ui:composition>
</html>

View File

@ -124,12 +124,12 @@
addMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}/text/@add"
canEdit="#{CmsSelectedDocumentModel.canEdit}"
editorPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}/text/@edit"
hasUnusedLocales="#{!CmsMpaSectionStep.hasUnusedTextLocales}"
hasUnusedLocales="#{CmsMpaSectionStep.hasUnusedTextLocales}"
removeMethod="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}/text/@remove"
sourceEditorPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}/text/@edit-source"
title="#{CmsMpaMessageBundle['text.editor.header']}"
unusedLocales="#{CmsMpaSectionStep.unusedTextLocales}"
variants="#{CmsMpaSectionStep.textValues}"
variants="#{CmsMpaSectionStep.textVariants}"
viewPageUrl="#{mvc.basePath}/#{ContentSectionModel.sectionName}/documents/#{CmsSelectedDocumentModel.itemPath}/@mpa-sections/#{CmsMpaSectionStep.sectionId}/text/@view"
/>

View File

@ -138,3 +138,5 @@ sectionstep.title.edit.remove.dialog.cancel=Cancel
sectionstep.title.edit.remove.dialog.submit=Remove localized title
sectionstep.title.edit.remove.dialog.text=Are you sure to remove to this localized title?
sectionstep.title.edit.remove.dialog.title=Remove localized title
sectionstep.textstep.header.view=Preview of text for locale {2} of section {1} of multipart article {0}
sectionsstep.text.editor.add.locale.help=The locale of the text.

View File

@ -110,7 +110,7 @@ sectionstep.pagebreak.edit.dialog.submit=Anwenden
sectionstep.text.editor.add_variant=Lokalisierten Text hinzuf\u00fcgen
text.editor.header=Text
sectionstep.textstep.back=Zur\u00fcck
sectionstep.textstep.header.edit=Text f\u00fcr Sprache {2} des Abschnitts {1} des mehrteiligen Artikels {0} bearbeiten
sectionstep.textstep.header.edit=Text in Sprache {2} des Abschnitts {1} des mehrteiligen Artikels {0} bearbeiten
sectionstep.textstep.text.editor.header=Text
authoringsteps.sections.label=Abschnitte
sectionsstep.sections.empty=Diese mehrteilige Artikel hat noch keine Abschnitte.
@ -138,3 +138,5 @@ sectionstep.title.edit.remove.dialog.cancel=Abbrechen
sectionstep.title.edit.remove.dialog.submit=Lokalisierten Titel entfernen
sectionstep.title.edit.remove.dialog.text=Sind Sie sicher, dass Sie diesen lokaliserten Titel entfernen wollen?
sectionstep.title.edit.remove.dialog.title=Lokalisierten Titel entfernen
sectionstep.textstep.header.view=Vorschau f\u00fcr den Text der Sprache {2} des Abschnitts {1} des mehrteiligen Artikels {0}
sectionsstep.text.editor.add.locale.help=Die Sprache des Textes.

View File

@ -1,7 +1,7 @@
import { CmsEditorBuilder, CmsEditor } from "./cms-editor";
document.addEventListener("DOMContentLoaded", (event) => {
const editorElem = document.querySelector("#cms-article-text-editor");
const editorElem = document.querySelector("#cms-article-text-editor");
if (editorElem) {
const saveUrl = editorElem.getAttribute("data-save-url");

View File

@ -0,0 +1,51 @@
import { CmsEditorBuilder, CmsEditor } from "./cms-editor";
document.addEventListener("DOMContentLoaded", (event) => {
const editorElem = document.querySelector("#cms-mpa-section-text-editor");
if (editorElem) {
const saveUrl = editorElem.getAttribute("data-save-url");
const variantUrl = editorElem.getAttribute("data-variant-url");
if (!saveUrl) {
console.error("saveUrl is null");
return;
}
if (!variantUrl) {
console.error("variantUrl is null");
return;
}
const builder = new CmsEditorBuilder(
editorElem as HTMLElement,
saveUrl,
variantUrl
);
builder
.buildEditor()
.then((editor) => {
const submitButton = document.querySelector(
".cms-editor-save-button"
);
if (submitButton) {
submitButton.addEventListener("click", (event) => {
event.preventDefault();
console.log("HTML output of editor: ");
console.log(editor.getEditor().getHTML());
});
} else {
console.error("Save button not found.")
}
})
.catch((error) => {
console.error(error);
console.trace(error);
});
} else {
console.error("Editor element not found.")
}
});

View File

@ -6,7 +6,8 @@ module.exports = {
},
entry: {
"cms-admin": "./src/main/typescript/content-sections/cms-admin.ts",
"article-text-step": "./src/main/typescript/content-sections/article-text-step.ts"
"article-text-step": "./src/main/typescript/content-sections/article-text-step.ts",
"mpa-section-edit-text": "./src/main/typescript/content-sections/mpa-section-edit-text.ts"
},
output: {
filename: "[name].js",