From b526f9eac270983edf8fd70556fee1372ca01301 Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Mon, 10 May 2021 21:24:48 +0200 Subject: [PATCH] Current status text step --- ccm-cms/pom.xml | 5 + .../documents/CmsEditorLocaleVariantRow.java | 49 ++ .../contenttypes/MvcArticleTextBodyStep.java | 54 +- .../components/librecms/cmsEditor.xhtml | 560 ++++++++++++++++++ .../contenttypes/article/article-text.xhtml | 48 +- .../org/librecms/CmsAdminMessages.properties | 3 + .../librecms/CmsAdminMessages_de.properties | 3 + .../typescript/content-sections/cms-editor.ts | 69 ++- ccm-cms/tsconfig.json | 8 + 9 files changed, 765 insertions(+), 34 deletions(-) create mode 100644 ccm-cms/src/main/java/org/librecms/ui/contentsections/documents/CmsEditorLocaleVariantRow.java create mode 100644 ccm-cms/src/main/resources/META-INF/resources/components/librecms/cmsEditor.xhtml create mode 100644 ccm-cms/tsconfig.json diff --git a/ccm-cms/pom.xml b/ccm-cms/pom.xml index 980f81f68..c89a0d3de 100644 --- a/ccm-cms/pom.xml +++ b/ccm-cms/pom.xml @@ -114,6 +114,11 @@ org.apache.shiro shiro-web + + + org.jsoup + jsoup + junit diff --git a/ccm-cms/src/main/java/org/librecms/ui/contentsections/documents/CmsEditorLocaleVariantRow.java b/ccm-cms/src/main/java/org/librecms/ui/contentsections/documents/CmsEditorLocaleVariantRow.java new file mode 100644 index 000000000..d4cee6eda --- /dev/null +++ b/ccm-cms/src/main/java/org/librecms/ui/contentsections/documents/CmsEditorLocaleVariantRow.java @@ -0,0 +1,49 @@ +/* + * 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; + +/** + * + * @author Jens Pelzetter + */ +public class CmsEditorLocaleVariantRow { + + private String locale; + + private long wordCount; + + public String getLocale() { + return locale; + } + + public void setLocale(final String locale) { + this.locale = locale; + } + + public long getWordCount() { + return wordCount; + } + + public void setWordCount(final long wordCount) { + this.wordCount = wordCount; + } + + + +} diff --git a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStep.java b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStep.java index ced77f6da..cc0726bf9 100644 --- a/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStep.java +++ b/ccm-cms/src/main/java/org/librecms/ui/contenttypes/MvcArticleTextBodyStep.java @@ -20,6 +20,8 @@ package org.librecms.ui.contenttypes; import com.arsdigita.kernel.KernelConfig; +import org.jsoup.Jsoup; +import org.jsoup.nodes.Document; import org.libreccm.configuration.ConfigurationManager; import org.libreccm.l10n.GlobalizationHelper; import org.libreccm.l10n.LocalizedString; @@ -27,6 +29,7 @@ import org.librecms.contentsection.ContentItemRepository; import org.librecms.contenttypes.Article; import org.librecms.ui.contentsections.ItemPermissionChecker; import org.librecms.ui.contentsections.documents.AbstractMvcAuthoringStep; +import org.librecms.ui.contentsections.documents.CmsEditorLocaleVariantRow; import org.librecms.ui.contentsections.documents.ContentSectionNotFoundException; import org.librecms.ui.contentsections.documents.DocumentNotFoundException; import org.librecms.ui.contentsections.documents.DocumentUi; @@ -54,6 +57,7 @@ import javax.ws.rs.PathParam; import org.librecms.ui.contentsections.documents.MvcAuthoringStepDef; import java.util.Collections; +import java.util.StringTokenizer; /** * Authoring step for editing the main text of an {@link Article}. @@ -97,6 +101,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { private ItemPermissionChecker itemPermissionChecker; private Map textValues; + + private List variants; private List unusedLocales; @@ -125,8 +131,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { } if (itemPermissionChecker.canEditItem(getArticle())) { -// return "org/librecms/ui/contenttypes/article/article-text.xhtml"; - return "org/librecms/ui/contenttypes/article/article-text/available-languages.xhtml"; + return "org/librecms/ui/contenttypes/article/article-text.xhtml"; +// return "org/librecms/ui/contenttypes/article/article-text/available-languages.xhtml"; } else { return documentUi.showAccessDenied( getContentSection(), @@ -144,6 +150,10 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { public Map getTextValues() { return Collections.unmodifiableMap(textValues); } + + public List getVariants() { + return variants; + } /** * Gets the locales for which the main text has not been defined yet. @@ -168,7 +178,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { * @return A redirect to this authoring step. */ @POST - @Path("/@add") +// @Path("/@add") + @Path("/add") @Transactional(Transactional.TxType.REQUIRED) public String addTextValue( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -216,7 +227,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { } @GET - @Path("/{locale}/@view") +// @Path("/{locale}/@view") + @Path("/variants/{locale}") @Transactional(Transactional.TxType.REQUIRED) public String viewTextValue( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -236,7 +248,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { if (itemPermissionChecker.canEditItem(getArticle())) { selectedLocale = new Locale(localeParam).toString(); - return "org/librecms/ui/contenttypes/article/article-text/view.xhtml"; +// return "org/librecms/ui/contenttypes/article/article-text/view.xhtml"; + return getTextValues().get(localeParam); } else { return documentUi.showAccessDenied( getContentSection(), @@ -248,7 +261,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { @GET - @Path("/{locale}/@edit") +// @Path("/{locale}/@edit") + @Path("/edit/{locale}") @Transactional(Transactional.TxType.REQUIRED) public String editTextValue( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -289,7 +303,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { * @return A redirect to this authoring step. */ @POST - @Path("/{locale}/@edit") +// @Path("/{locale}/@edit") + @Path("/edit/{locale}") @Transactional(Transactional.TxType.REQUIRED) public String editTextValue( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -332,7 +347,8 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { * @return A redirect to this authoring step. */ @POST - @Path("/{locale}/@remove") +// @Path("/{locale}/@remove") + @Path("/remove/{locale}") @Transactional(Transactional.TxType.REQUIRED) public String removeTextValue( @PathParam(MvcAuthoringSteps.SECTION_IDENTIFIER_PATH_PARAM) @@ -381,6 +397,14 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { entry -> entry.getValue() ) ); + + variants = getArticle() + .getText() + .getValues() + .entrySet() + .stream() + .map(this::buildVariantRow) + .collect(Collectors.toList()); final Set locales = getArticle() .getText() @@ -397,5 +421,19 @@ public class MvcArticleTextBodyStep extends AbstractMvcAuthoringStep { private Article getArticle() { return (Article) getDocument(); } + + private CmsEditorLocaleVariantRow buildVariantRow( + final Map.Entry entry + ) { + final CmsEditorLocaleVariantRow variant = new CmsEditorLocaleVariantRow(); + variant.setLocale(entry.getKey().toString()); + final Document document = Jsoup.parseBodyFragment(entry.getValue()); + document.body().text(); + variant.setWordCount( + new StringTokenizer(document.body().text()).countTokens() + ); + + return variant; + } } diff --git a/ccm-cms/src/main/resources/META-INF/resources/components/librecms/cmsEditor.xhtml b/ccm-cms/src/main/resources/META-INF/resources/components/librecms/cmsEditor.xhtml new file mode 100644 index 000000000..f3a1a3856 --- /dev/null +++ b/ccm-cms/src/main/resources/META-INF/resources/components/librecms/cmsEditor.xhtml @@ -0,0 +1,560 @@ +]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + +

#{cc.attrs.title}

+
+ +

#{cc.attrs.title}

+
+ +

#{cc.attrs.title}

+
+ +

#{cc.attrs.title}

+
+ +
#{cc.attrs.title}
+
+ +
#{cc.attrs.title}
+
+ +
#{cc.attrs.title}
+
+
+
+ + + +
+ +
+
+ +
+ +
+
+ + +

+ #{cc.attrs.emptyText} +

+
+ + + + + + + + + + + + + + + + + + +
#{cc.attrs.tableLocaleHeading}#{cc.attrs.tableWordCountHeading}#{cc.attrs.tableActionsHeading}
#{variant.locale}#{CmsAdminMessages.getMessage('cms_editor.variants.wordcount', [variant.wordCount])} + + + + + + +
+
+
+
+ + +
+ diff --git a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contenttypes/article/article-text.xhtml b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contenttypes/article/article-text.xhtml index d8b879db1..a5c115fc3 100644 --- a/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contenttypes/article/article-text.xhtml +++ b/ccm-cms/src/main/resources/WEB-INF/views/org/librecms/ui/contenttypes/article/article-text.xhtml @@ -3,30 +3,44 @@ 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:librecms="http://xmlns.jcp.org/jsf/composite/components/librecms" xmlns:ui="http://xmlns.jcp.org/jsf/facelets">

#{CmsArticleMessageBundle['textstep.header']}

- - -
- + + + +
- + diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties index aafb40b41..0e9098cf0 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages.properties @@ -766,3 +766,6 @@ contentsection.configuration.workflows.task_details.assigned_to.title=Assigned r contentsection.configuration.workflow.task_details.assignments.dialog.roles.label=Roles contentsection.configuration.workflow.task_details.assignments.dialog.roles.help=Select the roles to which task is assigned. contentsection.configuration.workflows.task_details.assigned_to.dialog.title=Edit assigned roles +cms_editor.buttons.emph=Emphasized +cms_editor.buttons.strong_emph=Strong emphasized +cms_editor.variants.wordcount={0} words diff --git a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties index 6cf61aadb..b41875a79 100644 --- a/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties +++ b/ccm-cms/src/main/resources/org/librecms/CmsAdminMessages_de.properties @@ -767,3 +767,6 @@ contentsection.configuration.workflows.task_details.assigned_to.title=Zugewiesen contentsection.configuration.workflow.task_details.assignments.dialog.roles.label=Rollen contentsection.configuration.workflow.task_details.assignments.dialog.roles.help=W\u00e4hlen Sie die Rollen, denen die Aufgabe zugewiesen ist. contentsection.configuration.workflows.task_details.assigned_to.dialog.title=Zugewiesene Rollen bearbeiten +cms_editor.buttons.emph=Betont +cms_editor.buttons.strong_emph=Stark betont +cms_editor.variants.wordcount={0} W\u00f6rter diff --git a/ccm-cms/src/main/typescript/content-sections/cms-editor.ts b/ccm-cms/src/main/typescript/content-sections/cms-editor.ts index 60dfdf76e..2330d5e2c 100644 --- a/ccm-cms/src/main/typescript/content-sections/cms-editor.ts +++ b/ccm-cms/src/main/typescript/content-sections/cms-editor.ts @@ -1,15 +1,66 @@ +import "bootstrap"; +import * as $ from "jquery"; import { Editor } from "@tiptap/core"; import StarterKit from "@tiptap/starter-kit"; document.addEventListener("DOMContentLoaded", function (event) { - console.log("Starting editor"); - new Editor({ - element: document.querySelector('#cms-editor'), - extensions: [ - StarterKit - ], - content: '

Hello World

' - }) + document + .querySelector( + ".cms-editor .cms-editor-variants .cms-editor-view-button" + ) + .addEventListener("click", function (event) { + event.preventDefault(); + const target = event.currentTarget as Element; + const variantUrl = target.getAttribute("data-variant-url"); + const viewDialogId = target.getAttribute("data-view-dialog"); -}) + fetch(variantUrl, { + method: "GET", + credentials: "include" + }) + .then(response => { + if (response.ok) { + response + .text() + .then(text => { + const viewDialog = document.querySelector( + `#${viewDialogId}` + ); + const viewDialogBody = viewDialog.querySelector( + ".modal-body" + ); + + viewDialogBody.textContent = text; + + $(`#${viewDialogId}`).modal('toggle'); + }) + .catch(err => { + const template = document.querySelector( + "#cms-editor-msg-variant-load-failed" + ) as HTMLTemplateElement; + const msg = template.content.cloneNode(true); + document + .querySelector(".cms-editor-messages") + .append(msg); + }); + } + }) + .catch(err => { + const template = document.querySelector( + "#cms-editor-msg-variant-load-failed" + ) as HTMLTemplateElement; + const msg = template.content.cloneNode(true); + document.querySelector(".cms-editor-messages").append(msg); + }); + }); + + // console.log("Starting editor"); + // new Editor({ + // element: document.querySelector('#cms-editor'), + // extensions: [ + // StarterKit + // ], + // content: '

Hello World

' + // }) +}); diff --git a/ccm-cms/tsconfig.json b/ccm-cms/tsconfig.json new file mode 100644 index 000000000..b6150ddfc --- /dev/null +++ b/ccm-cms/tsconfig.json @@ -0,0 +1,8 @@ +{ + "compilerOptions": { + "lib": [ + "DOM", + "ES2016" + ] + } +} \ No newline at end of file