diff --git a/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/CourseCreationMailHelper.java b/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/CourseCreationMailHelper.java index 9bc94beba16d1e9a3c6878cce79d7891d7aeda57..9ddcf24037c739fa88cda90d72414e46da45728a 100644 --- a/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/CourseCreationMailHelper.java +++ b/src/main/java/de/tuchemnitz/wizard/workflows/coursecreation/CourseCreationMailHelper.java @@ -103,8 +103,10 @@ public class CourseCreationMailHelper { body += translator.translate("mail.body.4.6", new String[] {Integer.toString(++counter)}); } body += translator.translate("mail.body.5"); - String url = CoreSpringFactory.getImpl(HelpModule.class).getHelpProvider().getURL(ureq.getLocale(), ""); - body += translator.translate("mail.body.6", new String[]{ url }); + if (CoreSpringFactory.getImpl(HelpModule.class).isManualEnabled()) { + String url = CoreSpringFactory.getImpl(HelpModule.class).getManualProvider().getURL(ureq.getLocale(), ""); + body += translator.translate("mail.body.6", new String[]{ url }); + } body += translator.translate("mail.body.greetings"); MailBundle bundle = new MailBundle(); diff --git a/src/main/java/org/olat/_spring/extensionContext.xml b/src/main/java/org/olat/_spring/extensionContext.xml index ecfaddd8630908bef5ed3fbb40ada1befc8a4e0d..d256b5da58844bb14065ca61e57460260669bb15 100644 --- a/src/main/java/org/olat/_spring/extensionContext.xml +++ b/src/main/java/org/olat/_spring/extensionContext.xml @@ -520,10 +520,29 @@ </property> </bean> + <!-- Help module --> + <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> + <property name="order" value="7401" /> + <property name="actionController"> + <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> + <property name="className" value="org.olat.admin.help.ui.HelpAdminController"/> + </bean> + </property> + <property name="navigationKey" value="help" /> + <property name="translationPackage" value="org.olat.admin" /> + <property name="i18nActionKey" value="menu.help"/> + <property name="i18nDescriptionKey" value="menu.help.alt"/> + <property name="extensionPoints"> + <list> + <value>org.olat.admin.SystemAdminMainController</value> + </list> + </property> + <property name="parentTreeNodeIdentifier" value="sysAdminMenueNodeCustomizing" /> + </bean> <!-- Customizin / "Sprachanpassungswerkzeug" --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> - <property name="order" value="7401" /> + <property name="order" value="7402" /> <property name="actionController"> <bean class="org.olat.core.gui.control.creator.FactoryControllerCreator" scope="prototype"> <property name="factoryName" value="org.olat.core.util.i18n.ui.I18nUIFactory"/> @@ -544,7 +563,7 @@ <!-- System registration --> <bean class="org.olat.core.extensions.action.GenericActionExtension" init-method="initExtensionPoints"> - <property name="order" value="7402" /> + <property name="order" value="7403" /> <property name="actionController"> <bean class="org.olat.core.gui.control.creator.AutoCreator" scope="prototype"> <property name="className" value="org.olat.admin.registration.SystemRegistrationAdminController"/> diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties index bc3a551f01ec2dde778e05402caf4ca5fa47c60a..8920e0b593734a60f8f17b535a913397645835d1 100644 --- a/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_de.properties @@ -30,6 +30,8 @@ menu.external.tools=Externe Werkzeuge menu.external.tools.alt=Anbindung zu externen System menu.filesfolders=Dateien und Ordner menu.filesfolders.alt=Grosse Dateien, Versionseinstellungen und mehr +menu.help=Hilfe +menu.help.alt=Hilfe menu.hibernate=Database ORM menu.hibernate.alt=Database ORM / Hibernate menu.i18n=Sprachen diff --git a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties index ac3f3284a0f08ac5478209c070211b90145338cc..8a07a0606ec3f3301c07dcc6f7eb017f4ee8795f 100644 --- a/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/admin/_i18n/LocalStrings_en.properties @@ -30,6 +30,8 @@ menu.external.tools=External tools menu.external.tools.alt=Integration to external tools menu.filesfolders=Files and folders menu.filesfolders.alt=Large files, version settings and more +menu.help=Help +menu.help.alt=Help menu.hibernate=Database ORM menu.hibernate.alt=Database ORM / Hibernate menu.i18n=Languages diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminController.java b/src/main/java/org/olat/admin/help/ui/HelpAdminController.java new file mode 100644 index 0000000000000000000000000000000000000000..296509c8d3e64e9e5ace241a411ba02b65eb59fa --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminController.java @@ -0,0 +1,441 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.atomic.AtomicInteger; + +import org.olat.admin.help.ui.HelpAdminTableModel.HelpAdminTableColumn; +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.dropdown.DropdownItem; +import org.olat.core.gui.components.dropdown.DropdownOrientation; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; +import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.updown.UpDown; +import org.olat.core.gui.components.updown.UpDownEvent; +import org.olat.core.gui.components.updown.UpDownEvent.Direction; +import org.olat.core.gui.components.updown.UpDownFactory; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Date: 01 Apr 2020 + * @author aboeckle + */ +public class HelpAdminController extends FormBasicController { + + private static final String TABLE_NAME = "help_table"; + + private final AtomicInteger counter = new AtomicInteger(); + + private HelpAdminTableModel tableModel; + private FlexiTableElement tableEl; + private DefaultFlexiColumnModel upDownColumn; + + private DropdownItem addHelpDropDown; + private FormLink addAcademy; + private FormLink addConfluence; + private FormLink addCourse; + private FormLink addSupport; + private FormLink addCustom1; + private FormLink addCustom2; + private FormLink addCustom3; + + private CloseableModalController cmc; + private HelpAdminEditController editController; + private HelpAdminEditController addController; + private HelpAdminDeleteConfirmController deleteConfirmController; + + + @Autowired + private HelpModule helpModule; + + public HelpAdminController(UserRequest ureq, WindowControl control) { + super(ureq, control, "help"); + + initForm(ureq); + loadData(); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + FormLayoutContainer layout = (FormLayoutContainer)formLayout; + layout.contextPut("isHelpEnabled", helpModule.isHelpEnabled()); + + addHelpDropDown = uifactory.addDropdownMenu("help.admin.add.help", "help.admin.add.help", formLayout, getTranslator()); + addHelpDropDown.setOrientation(DropdownOrientation.right); + addHelpDropDown.setVisible(helpModule.getRemainingPlugins().length > 0 ); + + addAcademy = uifactory.addFormLink("help.admin.academy", formLayout); + addConfluence = uifactory.addFormLink("help.admin.confluence", formLayout); + addCourse = uifactory.addFormLink("help.admin.course", formLayout); + addSupport = uifactory.addFormLink("help.admin.support", formLayout); + addCustom1 = uifactory.addFormLink("help.admin.custom1", formLayout); + addCustom2 = uifactory.addFormLink("help.admin.custom2", formLayout); + addCustom3 = uifactory.addFormLink("help.admin.custom3", formLayout); + + FlexiTableColumnModel columnModel = FlexiTableDataModelFactory.createFlexiTableColumnModel(); + + upDownColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.upDown); + DefaultFlexiColumnModel labelColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.label); + DefaultFlexiColumnModel iconColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.icon); + iconColumn.setCellRenderer(new HelpAdminTableIconRenderer()); + DefaultFlexiColumnModel actionColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.action); + DefaultFlexiColumnModel usertoolColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.usertool); + usertoolColumn.setCellRenderer(new HelpAdminTableBooleanCellRenderer()); + DefaultFlexiColumnModel authoringColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.authoring); + authoringColumn.setCellRenderer(new HelpAdminTableBooleanCellRenderer()); + DefaultFlexiColumnModel loginColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.dmz); + loginColumn.setCellRenderer(new HelpAdminTableBooleanCellRenderer()); + DefaultFlexiColumnModel editColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.edit); + DefaultFlexiColumnModel deleteColumn = new DefaultFlexiColumnModel(HelpAdminTableColumn.delete); + + columnModel.addFlexiColumnModel(upDownColumn); + columnModel.addFlexiColumnModel(labelColumn); + columnModel.addFlexiColumnModel(iconColumn); + columnModel.addFlexiColumnModel(actionColumn); + columnModel.addFlexiColumnModel(authoringColumn); + columnModel.addFlexiColumnModel(usertoolColumn); + columnModel.addFlexiColumnModel(loginColumn); + columnModel.addFlexiColumnModel(editColumn); + columnModel.addFlexiColumnModel(deleteColumn); + + tableModel = new HelpAdminTableModel(columnModel, ureq); + tableEl = uifactory.addTableElement(getWindowControl(), TABLE_NAME, tableModel, getTranslator(), formLayout); + tableEl.setCustomizeColumns(false); + } + + private void loadData() { + // Fill drop down element + for (String helpPlugin : helpModule.getRemainingPlugins()) { + switch (helpPlugin) { + case HelpModule.ACADEMY: + addHelpDropDown.addElement(addAcademy); + break; + case HelpModule.CONFLUENCE: + addHelpDropDown.addElement(addConfluence); + break; + case HelpModule.COURSE: + addHelpDropDown.addElement(addCourse); + break; + case HelpModule.SUPPORT: + addHelpDropDown.addElement(addSupport); + break; + case HelpModule.CUSTOM_1: + addHelpDropDown.addElement(addCustom1); + break; + case HelpModule.CUSTOM_2: + addHelpDropDown.addElement(addCustom2); + break; + case HelpModule.CUSTOM_3: + addHelpDropDown.addElement(addCustom3); + break; + default: + break; + } + } + + addHelpDropDown.reset(); + + // Fill table + List<HelpAdminTableContentRow> tableRows = new ArrayList<>(); + List<String> helpPlugins = helpModule.getHelpPluginList(); + for (int i = 0; i < helpPlugins.size(); i++) { + String helpPlugin = helpPlugins.get(i); + HelpAdminTableContentRow tableRow; + + switch (helpPlugin) { + case HelpModule.ACADEMY_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.ACADEMY, + helpModule.getAcademyIcon(), + helpModule.getAcademyEnabled().contains(HelpModule.USERTOOL), + helpModule.getAcademyEnabled().contains(HelpModule.AUTHORSITE), + helpModule.getAcademyEnabled().contains(HelpModule.DMZ)); + break; + case HelpModule.CONFLUENCE_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.CONFLUENCE, + helpModule.getConfluenceIcon(), + helpModule.getConfluenceEnabled().contains(HelpModule.USERTOOL), + helpModule.getConfluenceEnabled().contains(HelpModule.AUTHORSITE), + helpModule.getConfluenceEnabled().contains(HelpModule.DMZ)); + break; + case HelpModule.COURSE_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.COURSE, + helpModule.getCourseIcon(), + helpModule.getCourseEnabled().contains(HelpModule.USERTOOL), + helpModule.getCourseEnabled().contains(HelpModule.AUTHORSITE), + helpModule.getCourseEnabled().contains(HelpModule.DMZ)); + break; + case HelpModule.CUSTOM_1_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.CUSTOM_1, + helpModule.getCustom1Icon(), + helpModule.getCustom1Enabled().contains(HelpModule.USERTOOL), + helpModule.getCustom1Enabled().contains(HelpModule.AUTHORSITE), + helpModule.getCustom1Enabled().contains(HelpModule.DMZ)); + break; + case HelpModule.CUSTOM_2_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.CUSTOM_2, + helpModule.getCustom2Icon(), + helpModule.getCustom2Enabled().contains(HelpModule.USERTOOL), + helpModule.getCustom2Enabled().contains(HelpModule.AUTHORSITE), + helpModule.getCustom2Enabled().contains(HelpModule.DMZ)); + break; + case HelpModule.CUSTOM_3_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.CUSTOM_3, + helpModule.getCustom3Icon(), + helpModule.getCustom3Enabled().contains(HelpModule.USERTOOL), + helpModule.getCustom3Enabled().contains(HelpModule.AUTHORSITE), + helpModule.getCustom3Enabled().contains(HelpModule.DMZ)); + break; + case HelpModule.SUPPORT_KEY: + tableRow = new HelpAdminTableContentRow( + HelpModule.SUPPORT, + helpModule.getSupportIcon(), + helpModule.getSupportEnabled().contains(HelpModule.USERTOOL), + helpModule.getSupportEnabled().contains(HelpModule.AUTHORSITE), + helpModule.getSupportEnabled().contains(HelpModule.DMZ)); + break; + default: + tableRow = new HelpAdminTableContentRow(); + break; + } + + if (helpPlugins.size() > 1) { + tableEl.setColumnModelVisible(upDownColumn, true); + UpDown upDown = UpDownFactory.createUpDown("up_down_" + helpPlugin, UpDown.Layout.LINK_HORIZONTAL, flc.getFormItemComponent(), this); + upDown.setUserObject(tableRow); + if (i == 0) { + upDown.setTopmost(true); + } else if (i == helpPlugins.size() - 1) { + upDown.setLowermost(true); + } + tableRow.setUpDown(upDown); + } else { + tableEl.setColumnModelVisible(upDownColumn, false); + } + + FormLink editLink = uifactory.addFormLink("edit_" + counter.incrementAndGet(), "edit", "help.admin.edit", null, null, Link.LINK); + editLink.setUserObject(tableRow); + + FormLink deleteLink = uifactory.addFormLink("delete_" + counter.incrementAndGet(), "delete", "help.admin.delete", null, null, Link.LINK); + deleteLink.setUserObject(tableRow); + + tableRow.setEditLink(editLink); + tableRow.setDeleteLink(deleteLink); + + tableRows.add(tableRow); + } + + tableModel.setObjects(tableRows); + tableEl.reset(true, true, true); + + // Save positions, necessary if new entries added + saveHelpPluginPositions(tableRows); + } + + @Override + protected void formOK(UserRequest ureq) { + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if (source == addAcademy) { + doOpenAddHelpDialog(ureq, HelpModule.ACADEMY); + } else if (source == addConfluence) { + doOpenAddHelpDialog(ureq, HelpModule.CONFLUENCE); + } else if (source == addCourse) { + doOpenAddHelpDialog(ureq, HelpModule.COURSE); + } else if (source == addSupport) { + doOpenAddHelpDialog(ureq, HelpModule.SUPPORT); + } else if (source == addCustom1) { + doOpenAddHelpDialog(ureq, HelpModule.CUSTOM_1); + } else if (source == addCustom2) { + doOpenAddHelpDialog(ureq, HelpModule.CUSTOM_2); + } else if (source == addCustom3) { + doOpenAddHelpDialog(ureq, HelpModule.CUSTOM_3); + } else if(source instanceof FormLink) { + FormLink link = (FormLink) source; + + if("edit".equals(link.getCmd())) { + HelpAdminTableContentRow row = (HelpAdminTableContentRow) link.getUserObject(); + + doOpenEditHelpDialog(ureq, row); + } else if ("delete".equals(link.getCmd())) { + HelpAdminTableContentRow row = (HelpAdminTableContentRow) link.getUserObject(); + + doOpenDeleteHelpDialog(ureq, row); + } + } + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == editController) { + if (event.equals(FormEvent.CANCELLED_EVENT)) { + cleanUp(); + } else if (event.equals(FormEvent.DONE_EVENT)) { + cleanUp(); + loadData(); + } + } else if (source == deleteConfirmController) { + if (event.equals(FormEvent.CANCELLED_EVENT)) { + cleanUp(); + } else if (event.equals(FormEvent.DONE_EVENT)) { + cleanUp(); + initForm(ureq); + loadData(); + } + } else if (source == addController) { + if (event.equals(FormEvent.CANCELLED_EVENT)) { + cleanUp(); + } else if (event.equals(FormEvent.DONE_EVENT)) { + cleanUp(); + initForm(ureq); + loadData(); + } + } else if (source == cmc) { + cleanUp(); + } + + super.event(ureq, source, event); + } + + @Override + public void event(UserRequest ureq, Component source, Event event) { + if (event instanceof UpDownEvent) { + UpDownEvent ude = (UpDownEvent) event; + doMoveHelpPlugin((UpDown)source, ude.getDirection()); + } + super.event(ureq, source, event); + } + + private void doMoveHelpPlugin(UpDown upDown, Direction direction) { + List<HelpAdminTableContentRow> tableRows = tableModel.getObjects(); + + Integer index = tableRows.indexOf(upDown.getUserObject()); + if (Direction.UP.equals(direction)) { + Collections.swap(tableRows, index - 1, index); + } else { + Collections.swap(tableRows, index, index + 1); + } + doDisableUpDowns(tableRows); + + tableModel.setObjects(tableRows); + tableEl.reset(true, true, true); + + saveHelpPluginPositions(tableRows); + } + + /** + * Hides up on the first line and down on the last line of the table + * @param tableRows + */ + private void doDisableUpDowns(List<HelpAdminTableContentRow> tableRows) { + + for (HelpAdminTableContentRow tableRow : tableRows) { + tableRow.getUpDown().setTopmost(false); + tableRow.getUpDown().setLowermost(false); + } + tableRows.get(0).getUpDown().setTopmost(true); + tableRows.get(tableRows.size()-1).getUpDown().setLowermost(true); + } + + private void saveHelpPluginPositions(List<HelpAdminTableContentRow> tableRows) { + for (HelpAdminTableContentRow tableRow : tableRows) { + helpModule.setPosition(tableRow.getHelpPlugin(), tableRows.indexOf(tableRow)); + } + + } + + @Override + protected void doDispose() { + // nothing to dispose + } + + private void cleanUp() { + if (cmc != null) { + cmc.deactivate(); + } + + removeAsListenerAndDispose(editController); + removeAsListenerAndDispose(addController); + removeAsListenerAndDispose(cmc); + + addController = null; + editController = null; + cmc = null; + + if (helpModule.getRemainingPlugins().length > 0) { + addHelpDropDown.reset(); + } + } + + private void doOpenAddHelpDialog(UserRequest ureq, String helpPluginToAdd) { + addController = new HelpAdminEditController(ureq, getWindowControl(), helpPluginToAdd); + listenTo(addController); + + cmc = new CloseableModalController(getWindowControl(), translate("close"), addController.getInitialComponent(), true, translate("help.admin.add.help"), true); + listenTo(cmc); + + cmc.activate(); + } + + private void doOpenEditHelpDialog(UserRequest ureq, HelpAdminTableContentRow row) { + editController = new HelpAdminEditController(ureq, getWindowControl(), row); + listenTo(editController); + + cmc = new CloseableModalController(getWindowControl(), translate("close"), editController.getInitialComponent(), true, translate("help.admin.edit.title"), true); + listenTo(cmc); + + cmc.activate(); + } + + private void doOpenDeleteHelpDialog(UserRequest ureq, HelpAdminTableContentRow row) { + deleteConfirmController = new HelpAdminDeleteConfirmController(ureq, getWindowControl(), row); + listenTo(deleteConfirmController); + + cmc = new CloseableModalController(getWindowControl(), translate("close"), deleteConfirmController.getInitialComponent(), true, translate("help.admin.delete.title"), true); + listenTo(cmc); + + cmc.activate(); + } +} \ No newline at end of file diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminDeleteConfirmController.java b/src/main/java/org/olat/admin/help/ui/HelpAdminDeleteConfirmController.java new file mode 100644 index 0000000000000000000000000000000000000000..b328c0f0cde9e84906123240284238639ccb0cf7 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminDeleteConfirmController.java @@ -0,0 +1,124 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.Util; +import org.springframework.beans.factory.annotation.Autowired; + +/* + * Date: 1 Apr 2020<br> + * @author Alexander Boeckle + */ +public class HelpAdminDeleteConfirmController extends FormBasicController { + + private final String description; + + private FormLink deleteButton; + private MultipleSelectionElement acknowledgeEl; + private HelpAdminTableContentRow tableRow; + + @Autowired + private HelpModule helpModule; + + public HelpAdminDeleteConfirmController(UserRequest ureq, WindowControl wControl, HelpAdminTableContentRow row) { + super(ureq, wControl, "delete_confirm"); + + Translator translator = Util.createPackageTranslator(HelpAdminController.class, ureq.getLocale()); + + this.description = translator.translate("help." + row.getHelpPlugin()); + this.tableRow = row; + + initForm(ureq); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + if(formLayout instanceof FormLayoutContainer) { + FormLayoutContainer layout = (FormLayoutContainer)formLayout; + + String confirmMessage = translate("dialog.confirm.message", description); + + layout.contextPut("confirmMessage", confirmMessage); + + FormLayoutContainer layoutCont = FormLayoutContainer.createDefaultFormLayout("confirm", getTranslator()); + formLayout.add("confirm", layoutCont); + layoutCont.setRootForm(mainForm); + + String[] acknowledge = new String[] { translate("dialog.confirm.delete.acknowledge") }; + acknowledgeEl = uifactory.addCheckboxesHorizontal("dialog.confirm", "dialog.confirm", layoutCont, new String[]{ "" }, acknowledge); + + FormLayoutContainer buttonsCont = FormLayoutContainer.createButtonLayout("buttons", getTranslator()); + layoutCont.add(buttonsCont); + uifactory.addFormCancelButton("cancel", buttonsCont, ureq, getWindowControl()); + deleteButton = uifactory.addFormLink("delete", buttonsCont, Link.BUTTON); + } + } + + @Override + protected void doDispose() { + // + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOk = super.validateFormLogic(ureq); + + acknowledgeEl.clearError(); + if(!acknowledgeEl.isAtLeastSelected(1)) { + acknowledgeEl.setErrorKey("dialog.confirm.error", null); + allOk &= false; + } + + return allOk; + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if(deleteButton == source) { + if(validateFormLogic(ureq)) { + formOK(ureq); + } + } + } + + @Override + protected void formOK(UserRequest ureq) { + helpModule.deleteHelpPlugin(tableRow.getHelpPlugin()); + fireEvent(ureq, FormEvent.DONE_EVENT); + } + + @Override + protected void formCancelled(UserRequest ureq) { + fireEvent(ureq, FormEvent.CANCELLED_EVENT); + } +} diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminEditController.java b/src/main/java/org/olat/admin/help/ui/HelpAdminEditController.java new file mode 100644 index 0000000000000000000000000000000000000000..69d0ac0432227c905c3f4f17b3cd28a14738b9b3 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminEditController.java @@ -0,0 +1,343 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; + +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.FormItem; +import org.olat.core.gui.components.form.flexible.FormItemContainer; +import org.olat.core.gui.components.form.flexible.elements.MultipleSelectionElement; +import org.olat.core.gui.components.form.flexible.elements.StaticTextElement; +import org.olat.core.gui.components.form.flexible.elements.TextElement; +import org.olat.core.gui.components.form.flexible.impl.FormBasicController; +import org.olat.core.gui.components.form.flexible.impl.FormEvent; +import org.olat.core.gui.components.form.flexible.impl.FormLayoutContainer; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.translator.TranslatorHelper; +import org.olat.core.util.StringHelper; +import org.olat.core.util.i18n.I18nItem; +import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; +import org.olat.core.util.mail.EmailAddressValidator; +import org.olat.course.CourseFactory; +import org.springframework.beans.factory.annotation.Autowired; + +/* + * Initial date: 8 Apr 2020<br> + * @author aboeckle, alexander.boeckle@frentix.com + */ +public class HelpAdminEditController extends FormBasicController { + + private final static String[] onKeys = new String[]{ "enabled" }; + + private Map<String, TextElement> labelElementsMap; + private TextElement iconEl; + private TextElement inputEl; + private MultipleSelectionElement displayEl; + private StaticTextElement typEl; + private MultipleSelectionElement newWindowEl; + + private String[] displayKeys = new String[3]; + private String[] displayValues = new String[displayKeys.length]; + private String[] onValues = new String[onKeys.length]; + + private String helpPlugin; + + @Autowired + private HelpModule helpModule; + @Autowired + private I18nModule i18nModule; + @Autowired + private I18nManager i18nManager; + + public HelpAdminEditController(UserRequest ureq, WindowControl wControl, String helpPluginToAdd) { + super(ureq, wControl); + + init(); + initForm(ureq); + + this.helpPlugin = helpPluginToAdd; + typEl.setValue(translate("help.admin." + helpPluginToAdd)); + setInputLabel(helpPlugin); + } + + public HelpAdminEditController(UserRequest ureq, WindowControl wControl, HelpAdminTableContentRow row) { + super(ureq, wControl); + + init(); + initForm(ureq); + + this.helpPlugin = row.getHelpPlugin(); + setInputLabel(helpPlugin); + + iconEl.setValue(StringHelper.containsNonWhitespace(row.getIcon()) ? row.getIcon() : HelpModule.DEFAULT_ICON); + typEl.setValue(translate("help.admin." + helpPlugin)); + typEl.setEnabled(false); + displayEl.select(displayKeys[0], row.isAuthoringSet()); + displayEl.select(displayKeys[1], row.isUsertoolSet()); + displayEl.select(displayKeys[2], row.isLoginSet()); + } + + private void init() { + labelElementsMap = new HashMap<>(); + + for (int i = 0; i < onKeys.length; i++) { + onValues[i] = translate(onKeys[i]); + } + + displayKeys[0] = "help.admin.display.authorsite"; + displayKeys[1] = "help.admin.display.usertool"; + displayKeys[2] = "help.admin.display.login"; + + displayValues = TranslatorHelper.translateAll(getTranslator(), displayKeys); + } + + private void setInputLabel(String helpPlugin) { + // Enable the DMZ location in case it was hidden + displayEl.setEnabled("help.admin.display.login", true); + + switch (helpPlugin) { + case HelpModule.ACADEMY: + inputEl.setLabel("help.admin.input.academy", null); + inputEl.setValue(helpModule.getAcademyLink()); + iconEl.setValue("o_icon_video"); + setElementVisible(inputEl, true, true, true); + break; + case HelpModule.CONFLUENCE: + String[] confluenceKeys = new String[displayKeys.length + 1]; + System.arraycopy(displayKeys, 0, confluenceKeys, 1, displayKeys.length); + confluenceKeys[0] = "help.admin.display.context"; + String[] confluenceValues = TranslatorHelper.translateAll(getTranslator(), confluenceKeys); + + displayEl.setKeysAndValues(confluenceKeys, confluenceValues); + displayEl.setEnabled("help.admin.display.context", false); + displayEl.select("help.admin.display.context", true); + + inputEl.setLabel("help.admin.input.confluence", null); + iconEl.setValue("o_icon_manual"); + setElementVisible(inputEl, false, false, false); + break; + case HelpModule.SUPPORT: + inputEl.setLabel("help.admin.input.support", null); + inputEl.setValue(helpModule.getSupportEmail()); + iconEl.setValue("o_icon_mail"); + setElementVisible(inputEl, true, true, true); + break; + case HelpModule.COURSE: + inputEl.setLabel("help.admin.input.course", null); + setElementVisible(inputEl, true, true, true); + inputEl.setValue(helpModule.getCourseSoftkey()); + // Disable the DMZ for legacy course help + displayEl.setEnabled("help.admin.display.login", false); + iconEl.setValue("o_course_icon"); + break; + case HelpModule.CUSTOM_1: + inputEl.setLabel("help.admin.input.url", null); + newWindowEl.select(onKeys[0], helpModule.isCustom1NewWindow()); + inputEl.setValue(helpModule.getCustom1Link()); + iconEl.setValue("o_icon_external_link"); + setElementVisible(inputEl, true, true, true); + setElementVisible(newWindowEl, true, true, false); + break; + case HelpModule.CUSTOM_2: + inputEl.setLabel("help.admin.input.url", null); + newWindowEl.select(onKeys[0], helpModule.isCustom2NewWindow()); + inputEl.setValue(helpModule.getCustom2Link()); + iconEl.setValue("o_icon_external_link"); + setElementVisible(inputEl, true, true, true); + setElementVisible(newWindowEl, true, true, false); + case HelpModule.CUSTOM_3: + inputEl.setLabel("help.admin.input.url", null); + newWindowEl.select(onKeys[0], helpModule.isCustom3NewWindow()); + inputEl.setValue(helpModule.getCustom3Link()); + iconEl.setValue("o_icon_external_link"); + setElementVisible(inputEl, true, true, true); + setElementVisible(newWindowEl, true, true, false); + break; + default: + break; + } + + for (String locale : i18nModule.getEnabledLanguageKeys()) { + String translation = i18nManager.getLocalizedString(HelpAdminController.class.getPackage().getName(), "help." + helpPlugin, null, Locale.forLanguageTag(locale), false, false, false, false, 0); + String overlayTranslation = i18nManager.getLocalizedString(HelpAdminController.class.getPackage().getName(), "help." + helpPlugin, null, Locale.forLanguageTag(locale), true, false, false, false, 0); + + if (translation != null && overlayTranslation != null && translation.equals(overlayTranslation)) { + labelElementsMap.get(locale).setPlaceholderText(translation); + } else { + labelElementsMap.get(locale).setValue(overlayTranslation); + } + } + } + + private void setElementVisible(FormItem formItem, boolean visible, boolean enabled, boolean mandatory) { + formItem.setVisible(visible); + formItem.setEnabled(enabled); + formItem.setMandatory(mandatory); + } + + @Override + protected void initForm(FormItemContainer formLayout, Controller listener, UserRequest ureq) { + FormLayoutContainer buttonLayout = FormLayoutContainer.createButtonLayout("buttonLayout", getTranslator()); + buttonLayout.setRootForm(mainForm); + + typEl = uifactory.addStaticTextElement("help.admin.type", "", formLayout); + for (String language : i18nModule.getEnabledLanguageKeys()) { + TextElement languageEl = uifactory.addTextElement("help.admin.label." + language, 255, "", formLayout); + languageEl.setLabel(translate("help.admin.label") + " " + language.toUpperCase(), null, false); + labelElementsMap.put(language, languageEl); + } + iconEl = uifactory.addTextElement("help.admin.icon", 255, "", formLayout); + iconEl.setValue(HelpModule.DEFAULT_ICON); + iconEl.setExampleKey("help.admin.icon.examples", new String[] {"o_icon_help, o_icon_video, o_icon_wiki, o_course_icon, o_icon_external_link, o_icon_link, ..."}); + iconEl.setMandatory(true); + inputEl = uifactory.addTextElement("help.admin.input.support", 255, "", formLayout); + inputEl.setMandatory(true); + newWindowEl = uifactory.addCheckboxesVertical("help.admin.new.window", formLayout, onKeys, onValues, 1); + setElementVisible(newWindowEl, false, false, false); + displayEl = uifactory.addCheckboxesVertical("help.admin.display", formLayout, displayKeys, displayValues, 1); + + uifactory.addFormCancelButton("cancel", buttonLayout, ureq, getWindowControl()); + uifactory.addFormSubmitButton("submit", buttonLayout); + formLayout.add(buttonLayout); + } + + @Override + protected void formCancelled(UserRequest ureq) { + super.formCancelled(ureq); + + fireEvent(ureq, FormEvent.CANCELLED_EVENT); + } + + @Override + protected void formOK(UserRequest ureq) { + helpModule.saveHelpPlugin( + helpPlugin, + iconEl.getValue(), + inputEl.getValue(), + displayEl.getSelectedKeys().contains("help.admin.display.usertool"), + displayEl.getSelectedKeys().contains("help.admin.display.authorsite"), + displayEl.getSelectedKeys().contains("help.admin.display.login"), + newWindowEl.getSelectedKeys().contains(onKeys[0])); + + // save new values + Map<Locale, Locale> allOverlays = i18nModule.getOverlayLocales(); + for (String locale : i18nModule.getEnabledLanguageKeys()) { + String newValue = labelElementsMap.get(locale).getValue(); + I18nItem item = i18nManager.getI18nItem(HelpAdminController.class.getPackage().getName(), "help." + helpPlugin, allOverlays.get(Locale.forLanguageTag(locale))); + i18nManager.saveOrUpdateI18nItem(item, newValue); + } + + fireEvent(ureq, FormEvent.DONE_EVENT); + } + + @Override + protected void doDispose() { + + } + + @Override + protected boolean validateFormLogic(UserRequest ureq) { + boolean allOK = super.validateFormLogic(ureq); + + for (String language : i18nModule.getEnabledLanguageKeys()) { + allOK &= validateTextInput(labelElementsMap.get(language), 255, false); + } + allOK &= validateTextInput(iconEl, 255, false); + + switch (helpPlugin) { + case HelpModule.SUPPORT: + allOK &= validateTextInput(inputEl, 255, true); + break; + case HelpModule.CUSTOM_1: + case HelpModule.CUSTOM_2: + case HelpModule.CUSTOM_3: + allOK &= validateTextInput(inputEl, 255, false); + break; + case HelpModule.COURSE: + allOK &= validateTextInput(inputEl, 255, false); + if (allOK) { + allOK &= CourseFactory.isHelpCourseExisting(inputEl.getValue()); + if (!allOK) { + inputEl.setErrorKey("help.admin.course.key.wrong", null); + } + } + break; + default: + break; + } + + + return allOK; + } + + private boolean validateTextInput(TextElement textElement, int lenght, boolean isMail) { + textElement.clearError(); + if(StringHelper.containsNonWhitespace(textElement.getValue())) { + if (isMail) { + if (!EmailAddressValidator.isValidEmailAddress(textElement.getValue())) { + textElement.setErrorKey("help.admin.input.wrong.mail", null); + return false; + } + } if(lenght != -1 && textElement.getValue().length() > lenght) { + textElement.setErrorKey("input.toolong", new String[]{ String.valueOf(lenght) }); + return false; + } + } else if (textElement.isMandatory()) { + textElement.setErrorKey("form.legende.mandatory", null); + return false; + } + + return true; + } + + @Override + protected void formInnerEvent(UserRequest ureq, FormItem source, FormEvent event) { + if (source == typEl) { + if (event.wasTriggerdBy(FormEvent.ONCHANGE)) { + if (typEl.getValue().contains(HelpModule.ACADEMY)) { + helpPlugin = HelpModule.ACADEMY; + } else if (typEl.getValue().contains(HelpModule.CONFLUENCE)) { + helpPlugin = HelpModule.CONFLUENCE; + } else if (typEl.getValue().contains(HelpModule.COURSE)) { + helpPlugin = HelpModule.COURSE; + } else if (typEl.getValue().contains(HelpModule.CUSTOM_1)) { + helpPlugin = HelpModule.CUSTOM_1; + } else if (typEl.getValue().contains(HelpModule.CUSTOM_2)) { + helpPlugin = HelpModule.CUSTOM_2; + } else if (typEl.getValue().contains(HelpModule.CUSTOM_3)) { + helpPlugin = HelpModule.CUSTOM_3; + } else if (typEl.getValue().contains(HelpModule.SUPPORT)) { + helpPlugin = HelpModule.SUPPORT; + } + + setInputLabel(helpPlugin); + } + } + + super.formInnerEvent(ureq, source, event); + } + +} diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminTableBooleanCellRenderer.java b/src/main/java/org/olat/admin/help/ui/HelpAdminTableBooleanCellRenderer.java new file mode 100644 index 0000000000000000000000000000000000000000..d5c7846fc3599566eb860a313529f59413fe987d --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminTableBooleanCellRenderer.java @@ -0,0 +1,43 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; + +/* + * Initial date: 11 Apr 2020<br> + * @author aboeckle, alexander.boeckle@frentix.com + */ +public class HelpAdminTableBooleanCellRenderer implements FlexiCellRenderer { + @Override + public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, + URLBuilder ubu, Translator translator) { + if (cellValue instanceof Boolean) { + Boolean value = (Boolean) cellValue; + target.append(translator.translate(value ? "yes" : "no")); + } + } +} + diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminTableContentRow.java b/src/main/java/org/olat/admin/help/ui/HelpAdminTableContentRow.java new file mode 100644 index 0000000000000000000000000000000000000000..45b4daf8d8b269e34178d6c689a2775f36589fc9 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminTableContentRow.java @@ -0,0 +1,96 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import org.olat.core.gui.components.form.flexible.elements.FormLink; +import org.olat.core.gui.components.updown.UpDown; + +/* + * Initial date: 6 Apr 2020<br> + * @author Alexander Boeckle, alexander.boeckle@frentix.com + */ +public class HelpAdminTableContentRow { + + private String helpPlugin; + private String icon; + private boolean usertool; + private boolean authoring; + private boolean login; + private FormLink editLink; + private FormLink deleteLink; + private UpDown upDown; + + public HelpAdminTableContentRow() { + // Nothing to do here + } + + public HelpAdminTableContentRow(String helpPlugin, String icon, boolean usertool, boolean authoring, boolean login) { + this.helpPlugin = helpPlugin; + this.icon = icon; + this.usertool = usertool; + this.authoring = authoring; + this.login = login; + } + + // Getters and setters + public void setUpDown(UpDown upDown) { + this.upDown = upDown; + } + + public UpDown getUpDown() { + return upDown; + } + + public String getIcon() { + return icon; + } + + public String getHelpPlugin() { + return helpPlugin; + } + + public boolean isUsertoolSet() { + return usertool; + } + + public boolean isAuthoringSet() { + return authoring; + } + + public boolean isLoginSet() { + return login; + } + + public FormLink getEditLink() { + return editLink; + } + + public FormLink getDeleteLink() { + return deleteLink; + } + + public void setEditLink(FormLink editLink) { + this.editLink = editLink; + } + + public void setDeleteLink(FormLink deleteLink) { + this.deleteLink = deleteLink; + } +} diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminTableIconRenderer.java b/src/main/java/org/olat/admin/help/ui/HelpAdminTableIconRenderer.java new file mode 100644 index 0000000000000000000000000000000000000000..5d04f5ffd621bdcf358c5120de31a58eefb0d30c --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminTableIconRenderer.java @@ -0,0 +1,42 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiCellRenderer; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableComponent; +import org.olat.core.gui.render.Renderer; +import org.olat.core.gui.render.StringOutput; +import org.olat.core.gui.render.URLBuilder; +import org.olat.core.gui.translator.Translator; + +/* + * Initial date: 11 Apr 2020<br> + * @author aboeckle, alexander.boeckle@frentix.com + */ +public class HelpAdminTableIconRenderer implements FlexiCellRenderer { + @Override + public void render(Renderer renderer, StringOutput target, Object cellValue, int row, FlexiTableComponent source, + URLBuilder ubu, Translator translator) { + if (cellValue instanceof String) { + target.append("<i class='o_icon o_icon-fw " + (String)cellValue + "'> </i>"); + } + } +} + diff --git a/src/main/java/org/olat/admin/help/ui/HelpAdminTableModel.java b/src/main/java/org/olat/admin/help/ui/HelpAdminTableModel.java new file mode 100644 index 0000000000000000000000000000000000000000..6d22b14cb63b8dab0faad5b78a1fc327d310c05c --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/HelpAdminTableModel.java @@ -0,0 +1,120 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.admin.help.ui; + +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.form.flexible.impl.elements.table.DefaultFlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiColumnDef; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableColumnModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModel; +import org.olat.core.gui.components.form.flexible.impl.elements.table.FlexiTableDataModelFactory; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.Util; +import org.olat.core.util.i18n.I18nModule; + +/* + * Initial date: 1 Apr 2020<br> + * @author Alexander Boeckle, alexander.boeckle@frentix.com + */ +public class HelpAdminTableModel extends DefaultFlexiTableDataModel<HelpAdminTableContentRow> +implements FlexiTableDataModel<HelpAdminTableContentRow> { + + private final Translator translator; + private final Translator adminTranslator; + + public HelpAdminTableModel(FlexiTableColumnModel columnModel, UserRequest ureq) { + super(columnModel); + + adminTranslator = Util.createPackageTranslator(HelpAdminController.class, ureq.getLocale()); + translator = Util.createPackageTranslator(HelpAdminController.class, ureq.getLocale()); + } + + // Only for createCopyWithEmptyList + private HelpAdminTableModel(FlexiTableColumnModel columnModel) { + super(columnModel); + + adminTranslator = Util.createPackageTranslator(HelpAdminController.class, I18nModule.getDefaultLocale()); + translator = Util.createPackageTranslator(HelpAdminController.class, I18nModule.getDefaultLocale()); + } + + @Override + public Object getValueAt(int row, int col) { + HelpAdminTableContentRow helpAdminRow = getObject(row); + return getValueAt(helpAdminRow, col); + } + + public Object getValueAt(HelpAdminTableContentRow row, int col) { + switch (HelpAdminTableColumn.values()[col]) { + case label: + return translator.translate("help." + row.getHelpPlugin()); + case icon: + return row.getIcon(); + case action: + return adminTranslator.translate("help.admin." + row.getHelpPlugin()); + case usertool: + return row.isUsertoolSet(); + case authoring: + return row.isAuthoringSet(); + case dmz: + return row.isLoginSet(); + case edit: + return row.getEditLink(); + case delete: + return row.getDeleteLink(); + case position: + return getObjects().indexOf(row); + case upDown: + return row.getUpDown(); + default: + return "ERROR"; + } + } + + @Override + public DefaultFlexiTableDataModel<HelpAdminTableContentRow> createCopyWithEmptyList() { + return new HelpAdminTableModel(FlexiTableDataModelFactory.createFlexiTableColumnModel()); + + } + + public enum HelpAdminTableColumn implements FlexiColumnDef { + label("help.admin.label"), + icon("help.admin.icon"), + action("help.admin.action"), + usertool("help.admin.usertool"), + authoring("help.admin.authorsite"), + dmz("help.admin.login"), + edit("help.admin.edit"), + delete("help.admin.delete"), + plugin("help.admin.plugin"), + position("help.admin.position"), + upDown("help.admin.up.down"); + + private final String i18nHeaderKey; + + private HelpAdminTableColumn(String i18nHeaderKey) { + this.i18nHeaderKey = i18nHeaderKey; + } + + @Override + public String i18nHeaderKey() { + return i18nHeaderKey; + } + } +} diff --git a/src/main/java/org/olat/admin/help/ui/_content/delete_confirm.html b/src/main/java/org/olat/admin/help/ui/_content/delete_confirm.html new file mode 100644 index 0000000000000000000000000000000000000000..00137c1fe1b43001ff920e04a19cc8b23d31c621 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/_content/delete_confirm.html @@ -0,0 +1,4 @@ +<div class="o_error"> + $confirmMessage +</div> +$r.render("confirm") \ No newline at end of file diff --git a/src/main/java/org/olat/admin/help/ui/_content/help.html b/src/main/java/org/olat/admin/help/ui/_content/help.html new file mode 100644 index 0000000000000000000000000000000000000000..dbdc644efd0de452b4e7c7bc66e41b7f79487649 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/_content/help.html @@ -0,0 +1,14 @@ +## Min-heigt fixes drop down not displayed when table not filled +<fieldset style="min-height: 80vh"> + <legend>$r.translate("help.admin.title")</legend> + #if($isHelpEnabled) + <div class="pull-right"> + $r.render("help.admin.add.help") + </div> + $r.render("help_table") + #else + <div class="o_info"> + $r.translate("help.admin.is.disabled") + </div> + #end +</fieldset> \ No newline at end of file diff --git a/src/main/java/org/olat/admin/help/ui/_content/help_edit.html b/src/main/java/org/olat/admin/help/ui/_content/help_edit.html new file mode 100644 index 0000000000000000000000000000000000000000..f557e9d0c1bb72b6d975cbe6fb046afa23a9e9a3 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/_content/help_edit.html @@ -0,0 +1,4 @@ +<fieldset> + <legend>$r.translate("help.admin.edit.title")</legend> + $r.render("help_edit_form") +</fieldset> \ No newline at end of file diff --git a/src/main/java/org/olat/admin/help/ui/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/admin/help/ui/_i18n/LocalStrings_de.properties new file mode 100644 index 0000000000000000000000000000000000000000..4199526b6693497b25509707fa631349fa1f38cc --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/_i18n/LocalStrings_de.properties @@ -0,0 +1,49 @@ +#Tue Apr 28 01:11:00 CEST 2020 +dialog.confirm=Best\u00E4tigung +dialog.confirm.delete.acknowledge=Gel\u00F6schte Hilfem\u00F6glichkeiten k\u00F6nnen wiederhergestellt werden +dialog.confirm.error=Dies Feld ist notwendig +dialog.confirm.message=<i class\="o_icon o_icon-fw o_icon_important"> </i> M\u00F6chten Sie die Hilfem\u00F6glichkeit <strong>{0}</strong> l\u00F6schen? +help.admin.academy=Offizielle OpenOlat Academy +help.admin.action=Aktion +help.admin.add.help=Hilfem\u00F6glichkeit hinzuf\u00FCgen +help.admin.authorsite=Autorenbereich +help.admin.confluence=Offizielles OpenOlat Handbuch +help.admin.course=OpenOlat Kurs +help.admin.course.key.wrong=Es konnte kein Kurs gefunden werden. Bitte geben Sie eine g\u00FCltige ID oder Soft-ID ein. +help.admin.custom2=Benutzerdefinierte URL 2 +help.admin.custom3=Benutzerdefinierte URL 3 +help.admin.custom1=Benutzerdefinierte URL 1 +help.admin.delete=L\u00F6schen +help.admin.delete.title=Hilfem\u00F6glichkeit l\u00F6schen +help.admin.display=Anzeige +help.admin.display.authorsite=Autorenbereich +help.admin.display.context=Kontext +help.admin.display.login=Login +help.admin.display.usertool=Benutzerwerkzeug +help.admin.edit=Bearbeiten +help.admin.edit.title=Hilfem\u00F6glichkeit bearbeiten +help.admin.icon=Symbol +help.admin.icon.examples={0} +help.admin.input.academy=Academy URL +help.admin.input.confluence=Handbuch URL +help.admin.input.course=Kurs ID / Soft ID +help.admin.input.support=E-Mail-Adresse +help.admin.input.url=URL +help.admin.input.wrong.mail=Bitte geben Sie eine g\u00FCltige E-Mail-Adresse ein. +help.admin.is.disabled=Die Hilfe ist ausgeschaltet. +help.admin.label=Bezeichnung +help.admin.login=Login +help.admin.new.window=In neuem Fenster \u00F6ffnen +help.admin.support=Kontaktformular +help.admin.title=Hilfe +help.admin.type=Typ +help.admin.usertool=Benutzerwerkzeug +help.admin.up.down=Position +help.authoring=Hilfe \u0026 Anleitungen +help.academy=OpenOlat Academy +help.confluence=OpenOlat Handbuch +help.course=Hilfekurs +help.custom1=Weitere Hilfe +help.custom2=Weitere Hilfe +help.custom3=Weitere Hilfe +help.support=E-Mail Support diff --git a/src/main/java/org/olat/admin/help/ui/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/admin/help/ui/_i18n/LocalStrings_en.properties new file mode 100644 index 0000000000000000000000000000000000000000..8cf6fdfcceccf084afeddd9fb55d69f1a876fa49 --- /dev/null +++ b/src/main/java/org/olat/admin/help/ui/_i18n/LocalStrings_en.properties @@ -0,0 +1,50 @@ +#Tue Apr 28 01:11:00 CEST 2020 +dialog.confirm=Confirmation +dialog.confirm.delete.acknowledge=Deleted help facilities can be restored. +dialog.confirm.error=This field is mandatory +dialog.confirm.message=<i class\="o_icon o_icon-lg o_icon_important"> </i> Do you want to delete the help facility <strong>{0}</strong>? +help.admin.academy=Official OpenOlat Academy +help.admin.action=Action +help.admin.add.help=Add help option +help.admin.authorsite=Authoring +help.admin.confluence=Official OpenOlat Manual +help.admin.course=OpenOlat Course +help.admin.course.key.wrong=No course could be found. Please enter a valid ID or soft ID. +help.admin.custom1=Custom URL 1 +help.admin.custom2=Custom URL 2 +help.admin.custom3=Custom URL 3 +help.admin.delete=Delete +help.admin.delete.title=Delete help facility +help.admin.display=Display +help.admin.display.authorsite=Authoring +help.admin.display.context=Context +help.admin.display.login=Login +help.admin.display.usertool=User tool +help.admin.edit=Edit +help.admin.edit.title=Edit help facility +help.admin.icon=Icon +help.admin.icon.examples={0} +help.admin.input.academy=Academy URL +help.admin.input.confluence=Manual URL +help.admin.input.course=Course ID / Soft ID +help.admin.input.support=Mail address +help.admin.input.url=URL +help.admin.input.wrong.mail=Please enter a valid e-mail address. +help.admin.is.disabled=Help is disabled. +help.admin.label=Label +help.admin.login=Login +help.admin.new.window=Open in new window +help.admin.support=Contact form +help.admin.title=Help\t +help.admin.type=Type +help.admin.usertool=Usertool +help.admin.up.down=Position +help.academy=OpenOlat Academy +help.authoring=Help \u0026 instructions +help.confluence=OpenOlat Manual +help.course=Help course +help.custom1=Further help +help.custom2=Further help +help.custom3=Further help +help.support=E-mail support + diff --git a/src/main/java/org/olat/admin/user/tools/UserToolCategory.java b/src/main/java/org/olat/admin/user/tools/UserToolCategory.java index d12a5d7436750d696ba374a5416b561581484403..1035ca9ce376599cb28033b4beb48945686b7ea4 100644 --- a/src/main/java/org/olat/admin/user/tools/UserToolCategory.java +++ b/src/main/java/org/olat/admin/user/tools/UserToolCategory.java @@ -29,6 +29,6 @@ public enum UserToolCategory { search, personal, config, - system - + system, + help } diff --git a/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java b/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java index ce5203c1ac3b63d5c54303f212d4379de853c3e1..f42b0784257e9e928affc68aa8d724ea4ad1abc9 100644 --- a/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java +++ b/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumAdminController.java @@ -341,7 +341,6 @@ public class ImpressumAdminController extends FormBasicController { group.getEditButton().setIconLeftCSS(null); group.getDeleteButton().setVisible(false); } - // TODO AB No dirty } super.formInnerEvent(ureq, source, event); } diff --git a/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumUserTool.java b/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumUserTool.java index fb63f3960b75c441d078eb78b5d72c2a5890d500..f95f834708f742e4cf9505ea363fd09fa9328bbc 100644 --- a/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumUserTool.java +++ b/src/main/java/org/olat/core/commons/controllers/impressum/ImpressumUserTool.java @@ -44,7 +44,7 @@ public class ImpressumUserTool implements UserTool, ComponentEventListener { public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { Link impressumLink = LinkFactory.createLink("topnav.impressum", container, this); impressumLink.setTooltip("topnav.impressum.alt"); - impressumLink.setIconLeftCSS("o_icon o_icon_impress o_icon-lg"); + impressumLink.setIconLeftCSS("o_icon o_icon_impress o_icon-fw"); impressumLink.setAjaxEnabled(false); impressumLink.setTarget("_blank"); return impressumLink; @@ -53,6 +53,7 @@ public class ImpressumUserTool implements UserTool, ComponentEventListener { @Override public void dispatchEvent(UserRequest ureq, Component source, Event event) { ControllerCreator impressumControllerCreator = new ControllerCreator() { + @Override public Controller createController(UserRequest lureq, WindowControl lwControl) { return new ImpressumMainController(lureq, lwControl); } diff --git a/src/main/java/org/olat/core/commons/services/help/HelpLinkSPI.java b/src/main/java/org/olat/core/commons/services/help/HelpLinkSPI.java index 03686e43a5bbe8977841837b192d1fc5235c3614..8761adbc3fb15510f2f3944343b2cbba0c71a591 100644 --- a/src/main/java/org/olat/core/commons/services/help/HelpLinkSPI.java +++ b/src/main/java/org/olat/core/commons/services/help/HelpLinkSPI.java @@ -37,6 +37,9 @@ public interface HelpLinkSPI { public String getURL(Locale locale, String module); public UserTool getHelpUserTool(WindowControl wControl); - + public Component getHelpPageLink(UserRequest ureq, String title, String tooltip, String iconCSS, String elementCSS, String page); + + public String getPluginName(); + } diff --git a/src/main/java/org/olat/core/commons/services/help/HelpModule.java b/src/main/java/org/olat/core/commons/services/help/HelpModule.java index ed62c23e1833d9b3b67616c1b2cbd483fb0de686..e1bbb39b9c6447b30e3e2d3c64b362051646bfa6 100644 --- a/src/main/java/org/olat/core/commons/services/help/HelpModule.java +++ b/src/main/java/org/olat/core/commons/services/help/HelpModule.java @@ -19,10 +19,28 @@ */ package org.olat.core.commons.services.help; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.stream.Collectors; + +import org.olat.admin.help.ui.HelpAdminController; import org.olat.core.CoreSpringFactory; +import org.olat.core.commons.services.help.spi.AcademyLinkSPI; import org.olat.core.commons.services.help.spi.ConfluenceLinkSPI; +import org.olat.core.commons.services.help.spi.CourseHelpSPI; +import org.olat.core.commons.services.help.spi.CustomLink1SPI; +import org.olat.core.commons.services.help.spi.CustomLink2SPI; +import org.olat.core.commons.services.help.spi.CustomLink3SPI; +import org.olat.core.commons.services.help.spi.SupportMailSPI; import org.olat.core.configuration.AbstractSpringModule; import org.olat.core.util.coordinate.CoordinatorManager; +import org.olat.core.util.i18n.I18nItem; +import org.olat.core.util.i18n.I18nManager; +import org.olat.core.util.i18n.I18nModule; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; @@ -30,48 +48,736 @@ import org.springframework.stereotype.Service; /** * * Initial date: 07.01.2015<br> + * * @author srosse, stephane.rosse@frentix.com, http://www.frentix.com * */ @Service public class HelpModule extends AbstractSpringModule { - + + private final static String DELIMITER = ","; + + public final static String ACADEMY = "academy"; + public final static String ACADEMY_KEY = "ooAcademyLinkHelp"; + public final static String CONFLUENCE = "confluence"; + public final static String CONFLUENCE_KEY = "ooConfluenceLinkHelp"; + public final static String SUPPORT = "support"; + public final static String SUPPORT_KEY = "supportMailHelp"; + public final static String COURSE = "course"; + public final static String COURSE_KEY = "courseHelp"; + public final static String CUSTOM_1 = "custom1"; + public final static String CUSTOM_1_KEY = "customLink1Help"; + public final static String CUSTOM_2 = "custom2"; + public final static String CUSTOM_2_KEY = "customLink2Help"; + public final static String CUSTOM_3 = "custom3"; + public final static String CUSTOM_3_KEY = "customLink3Help"; + + public final static String AUTHORSITE = "authorsite"; + public final static String USERTOOL = "usertool"; + public final static String DMZ = "dmz"; + + public final static String DEFAULT_ICON = "o_icon_help"; + + private List<String> helpPluginList; + private List<HelpLinkSPI> userToolHelpPlugins; + private List<HelpLinkSPI> authorSiteHelpPlugins; + private List<HelpLinkSPI> dmzHelpPlugins; + + // General help settings @Value("${help.enabled:true}") private boolean helpEnabled; - @Value("${help.plugin:ooConfluenceHelp}") - private String providerId; + @Value("${help.plugin:ooConfluenceLinkHelp}") + private String helpPlugins; + + // Academy settings + @Value("${help.academy.link:https://www.openolat.org/academy}") + private String academyLink; + @Value("${help.academy.enabled:usertool,authorsite}") + private String academyEnabled; + @Value("${help.academy.icon:o_icon_video}") + private String academyIcon; + private int academyPos; + + // Confluence settings + @Value("${help.confluence.enabled:usertool,authorsite}") + private String confluenceEnabled; + @Value("${help.confluence.icon:o_icon_manual}") + private String confluenceIcon; + private int confluencePos; + + // Support settings + @Value("${help.support.email:mail@your.domain}") + private String supportEmail; + @Value("${help.support.enabled:}") + private String supportEnabled; + private String supportIcon; + private int supportPos; + + // Course settings + @Value("${help.course.softkey:OLAT::help-course_de.zip}") + private String courseSoftkey; + @Value("${help.course.enabled:}") + private String courseEnabled; + private String courseIcon; + private int coursePos; + + // Custom link 1 settings + @Value("${help.custom1.link:}") + private String custom1Link; + @Value("${help.custom1.new.window:false}") + private boolean custom1NewWindow; + @Value("${help.custom1.enabled:}") + private String custom1Enabled; + private String custom1Icon; + private int custom1Pos; + + // Custom link 2 settings + @Value("${help.custom2.link:}") + private String custom2Link; + @Value("${help.custom2.new.window:false}") + private boolean custom2NewWindow; + @Value("${help.custom2.enabled:}") + private String custom2Enabled; + private String custom2Icon; + private int custom2Pos; + + // Custom link 3 settings + @Value("${help.custom3.link:}") + private String custom3Link; + @Value("${help.custom3.new.window:false}") + private boolean custom3NewWindow; + @Value("${help.custom3.enabled:}") + private String custom3Enabled; + private String custom3Icon; + private int custom3Pos; @Autowired - private ConfluenceLinkSPI confluenceSpi; - + I18nManager i18nManager; @Autowired + I18nModule i18nModule; + public HelpModule(CoordinatorManager coordinatorManager) { super(coordinatorManager); } - - public HelpLinkSPI getHelpProvider( ) { - Object provider = CoreSpringFactory.getBean(providerId); - if(provider instanceof HelpLinkSPI) { - return(HelpLinkSPI)provider; + + @Override + public void init() { + loadProperties(); + } + + @Override + protected void initFromChangedProperties() { + loadProperties(); + } + + private void loadProperties() { + // General help settings + helpPlugins = getStringPropertyValue("help.plugin", helpPlugins); + + // Academy settings + academyLink = getStringPropertyValue("help.academy.link", academyLink); + academyEnabled = getStringPropertyValue("help.academy.enabled", academyEnabled); + academyIcon = getStringPropertyValue("help.academy.icon", academyIcon); + academyPos = getIntPropertyValue("help.academy.pos"); + + // Confluence settings + confluenceEnabled = getStringPropertyValue("help.confluence.enabled", confluenceEnabled); + confluenceIcon = getStringPropertyValue("help.confluence.icon", confluenceIcon); + confluencePos = getIntPropertyValue("help.confluence.pos"); + + // Support settings + supportEmail = getStringPropertyValue("help.support.email", supportEmail); + supportEnabled = getStringPropertyValue("help.support.enabled", supportEnabled); + supportIcon = getStringPropertyValue("help.support.icon", DEFAULT_ICON); + supportPos = getIntPropertyValue("help.support.pos"); + + // Course settings + courseSoftkey = getStringPropertyValue("help.course.softkey", courseSoftkey); + courseEnabled = getStringPropertyValue("help.course.enabled", courseEnabled); + courseIcon = getStringPropertyValue("help.course.icon", DEFAULT_ICON); + coursePos = getIntPropertyValue("help.course.pos"); + + // Custom link 1 settings + custom1Link = getStringPropertyValue("help.custom1.link", custom1Link); + custom1Enabled = getStringPropertyValue("help.custom1.enabled", custom1Enabled); + custom1NewWindow = getBooleanPropertyValue("help.custom1.new.window"); + custom1Icon = getStringPropertyValue("help.custom1.icon", DEFAULT_ICON); + + // Custom link 2 settings + custom2Link = getStringPropertyValue("help.custom2.link", custom2Link); + custom2Enabled = getStringPropertyValue("help.custom2.enabled", custom2Enabled); + custom2NewWindow = getBooleanPropertyValue("help.custom2.new.window"); + custom2Icon = getStringPropertyValue("help.custom2.icon", DEFAULT_ICON); + + // Custom link 2 settings + custom3Link = getStringPropertyValue("help.custom3.link", custom3Link); + custom3Enabled = getStringPropertyValue("help.custom3.enabled", custom3Enabled); + custom3NewWindow = getBooleanPropertyValue("help.custom3.new.window"); + custom3Icon = getStringPropertyValue("help.custom3.icon", DEFAULT_ICON); + } + + // CRUD operations + public HelpLinkSPI getManualProvider() { + // Manual provider for tool tips + return (ConfluenceLinkSPI)CoreSpringFactory.getBean("ooConfluenceLinkHelp"); + } + + public void deleteHelpPlugin(String plugin) { + // Position of the plugin which should be deleted + // Value is set to 100 because a greater or equals filter is applied later + int removalPosition = 100; + + // Remove language overlays + Map<Locale, Locale> allOverlays = i18nModule.getOverlayLocales(); + for (String locale : i18nModule.getEnabledLanguageKeys()) { + I18nItem item = i18nManager.getI18nItem(HelpAdminController.class.getPackage().getName(), "help." + plugin, allOverlays.get(Locale.forLanguageTag(locale))); + i18nManager.saveOrUpdateI18nItem(item, ""); + } + + // Remove settings + switch (plugin) { + case ACADEMY: + plugin = ACADEMY_KEY; + removalPosition = academyPos; + removeProperty("help.academy.link", true); + removeProperty("help.academy.icon", true); + removeProperty("help.academy.enabled", true); + removeProperty("help.academy.pos", true); + break; + case CONFLUENCE: + plugin = CONFLUENCE_KEY; + removalPosition = confluencePos; + removeProperty("help.confluence.icon", true); + removeProperty("help.confluence.enabled", true); + removeProperty("help.confluence.pos", true); + break; + case COURSE: + plugin = COURSE_KEY; + removalPosition = coursePos; + removeProperty("help.course.softkey", true); + removeProperty("help.course.icon", true); + removeProperty("help.course.enabled", true); + removeProperty("help.course.pos", true); + break; + case CUSTOM_1: + plugin = CUSTOM_1_KEY; + removalPosition = custom1Pos; + removeProperty("help.custom1.link", true); + removeProperty("help.custom1.icon", true); + removeProperty("help.custom1.enabled", true); + removeProperty("help.custom1.new.window", true); + removeProperty("help.custom1.pos", true); + break; + case CUSTOM_2: + plugin = CUSTOM_2_KEY; + removalPosition = custom2Pos; + removeProperty("help.custom2.link", true); + removeProperty("help.custom2.icon", true); + removeProperty("help.custom2.enabled", true); + removeProperty("help.custom2.new.window", true); + removeProperty("help.custom2.pos", true); + break; + case CUSTOM_3: + plugin = CUSTOM_3_KEY; + removalPosition = custom3Pos; + removeProperty("help.custom3.link", true); + removeProperty("help.custom3.icon", true); + removeProperty("help.custom3.enabled", true); + removeProperty("help.custom3.new.window", true); + removeProperty("help.custom3.pos", true); + break; + case SUPPORT: + plugin = SUPPORT_KEY; + removalPosition = supportPos; + removeProperty("help.support.email", true); + removeProperty("help.support.icon", true); + removeProperty("help.support.enabled", true); + removeProperty("help.support.pos", true); + break; + default: + break; } - return confluenceSpi; + + // Remove help plugin + helpPluginList.remove(plugin); + helpPlugins = helpPluginList.stream().collect(Collectors.joining(DELIMITER)); + setStringProperty("help.plugin", helpPlugins, true); + + // Adapt positions + for (String helpPlugin : helpPluginList) { + switch (helpPlugin) { + case ACADEMY_KEY: + if (academyPos > removalPosition) { + academyPos -= 1; + setIntProperty("help.academy.pos", academyPos, true); + } + break; + case CONFLUENCE_KEY: + if (confluencePos > removalPosition) { + confluencePos -= 1; + setIntProperty("help.confluence.pos", confluencePos, true); + } + break; + case COURSE_KEY: + if (coursePos > removalPosition) { + coursePos -= 1; + setIntProperty("help.course.pos", coursePos, true); + } + break; + case CUSTOM_1_KEY: + if (custom1Pos > removalPosition) { + custom1Pos -= 1; + setIntProperty("help.custom1.pos", custom1Pos, true); + } + break; + case CUSTOM_2_KEY: + if (custom2Pos > removalPosition) { + custom2Pos -= 1; + setIntProperty("help.custom2.pos", custom2Pos, true); + } + break; + case CUSTOM_3_KEY: + if (custom3Pos > removalPosition) { + custom3Pos -= 1; + setIntProperty("help.custom3.pos", custom3Pos, true); + } + break; + case SUPPORT_KEY: + if (supportPos > removalPosition) { + supportPos -= 1; + setIntProperty("help.support.pos", supportPos, true); + } + break; + default: + break; + } + } + + loadLists(); + } + + public void saveHelpPlugin(String plugin, String icon, String input, + boolean usertool, boolean authorsite, boolean login, boolean newWindow) { + switch (plugin) { + case ACADEMY: + academyLink = setStringProperty("help.academy.link", input, true); + academyIcon = setStringProperty("help.academy.icon", icon, true); + academyEnabled = setStringProperty("help.academy.enabled", generateEnabledString(usertool, authorsite, login), true); + addToHelpPlugins(ACADEMY_KEY); + break; + case CONFLUENCE: + confluenceEnabled = setStringProperty("help.confluence.enabled", generateEnabledString(usertool, authorsite, login), true); + confluenceIcon = setStringProperty("help.confluence.icon", icon, true); + addToHelpPlugins(CONFLUENCE_KEY); + break; + case COURSE: + courseSoftkey = setStringProperty("help.course.softkey", input, true); + courseEnabled = setStringProperty("help.course.enabled", generateEnabledString(usertool, authorsite, login), true); + courseIcon = setStringProperty("help.course.icon", icon, true); + addToHelpPlugins(COURSE_KEY); + break; + case CUSTOM_1: + custom1Link = setStringProperty("help.custom1.link", input, true); + custom1NewWindow = newWindow; + setBooleanProperty("help.custom1.new.window", newWindow, true); + custom1Enabled = setStringProperty("help.custom1.enabled", generateEnabledString(usertool, authorsite, login), true); + custom1Icon = setStringProperty("help.custom1.icon", icon, true); + addToHelpPlugins(CUSTOM_1_KEY); + break; + case CUSTOM_2: + custom2Link = setStringProperty("help.custom2.link", input, true); + custom2NewWindow = newWindow; + setBooleanProperty("help.custom2.new.window", newWindow, true); + custom2Enabled = setStringProperty("help.custom2.enabled", generateEnabledString(usertool, authorsite, login), true); + custom2Icon = setStringProperty("help.custom2.icon", icon, true); + addToHelpPlugins(CUSTOM_2_KEY); + break; + case CUSTOM_3: + custom3Link = setStringProperty("help.custom3.link", input, true); + custom3NewWindow = newWindow; + setBooleanProperty("help.custom3.new.window", newWindow, true); + custom3Enabled = setStringProperty("help.custom3.enabled", generateEnabledString(usertool, authorsite, login), true); + custom3Icon = setStringProperty("help.custom3.icon", icon, true); + addToHelpPlugins(CUSTOM_3_KEY); + break; + case SUPPORT: + supportEmail = setStringProperty("help.support.email", input, true); + supportEnabled = setStringProperty("help.support.enabled", generateEnabledString(usertool, authorsite, login), true); + supportIcon = setStringProperty("help.support.icon", icon, true); + addToHelpPlugins(SUPPORT_KEY); + break; + default: + break; + } + + loadLists(); } + // Getters and setters public boolean isHelpEnabled() { return helpEnabled; } + + /** + * Returns whether the confluence manual is enabled or not + * @return boolean + */ + public boolean isManualEnabled() { + return isHelpEnabled() && helpPluginList.contains(CONFLUENCE_KEY); + } public void setHelpEnabled(boolean helpEnabled) { this.helpEnabled = helpEnabled; + setBooleanProperty("help.enabled", helpEnabled, true); + } + + // Saves the order position + public void setPosition(String helpPlugin, int position) { + switch (helpPlugin) { + case ACADEMY: + academyPos = position; + setIntProperty("help.academy.pos", position, true); + break; + case CONFLUENCE: + confluencePos = position; + setIntProperty("help.confluence.pos", position, true); + break; + case COURSE: + coursePos = position; + setIntProperty("help.course.pos", position, true); + break; + case CUSTOM_1: + custom1Pos = position; + setIntProperty("help.custom1.pos", position, true); + break; + case CUSTOM_2: + custom2Pos = position; + setIntProperty("help.custom2.pos", position, true); + break; + case CUSTOM_3: + custom3Pos = position; + setIntProperty("help.custom3.pos", position, true); + break; + case SUPPORT: + supportPos = position; + setIntProperty("help.support.pos", position, true); + break; + default: + break; + } + + loadLists(); } - @Override - public void init() { - // + public List<String> getHelpPluginList() { + if (helpPluginList == null) { + loadLists(); + } + + return helpPluginList; } - @Override - protected void initFromChangedProperties() { - // + public List<HelpLinkSPI> getDMZHelpPlugins() { + if (dmzHelpPlugins == null) { + loadLists(); + } + + return dmzHelpPlugins; + } + public List<HelpLinkSPI> getAuthorSiteHelpPlugins() { + if (authorSiteHelpPlugins == null) { + loadLists(); + } + + return authorSiteHelpPlugins; + } + public List<HelpLinkSPI> getUserToolHelpPlugins() { + if (userToolHelpPlugins == null) { + loadLists(); + } + + return userToolHelpPlugins; + } + + public String getAcademyLink() { + return academyLink; + } + + public String getAcademyEnabled() { + return academyEnabled; + } + + public String getAcademyIcon() { + return academyIcon; + } + + public String getConfluenceEnabled() { + return confluenceEnabled; + } + + public String getConfluenceIcon() { + return confluenceIcon; + } + + public String getSupportEmail() { + return supportEmail; + } + + public String getSupportEnabled() { + return supportEnabled; + } + + public String getSupportIcon() { + return supportIcon; + } + + public String getCourseSoftkey() { + return courseSoftkey; + } + + public String getCourseEnabled() { + return courseEnabled; + } + + public String getCourseIcon() { + return courseIcon; + } + + public String getCustom1Link() { + return custom1Link; + } + + public boolean isCustom1NewWindow() { + return custom1NewWindow; + } + + public String getCustom1Enabled() { + return custom1Enabled; + } + + public String getCustom1Icon() { + return custom1Icon; + } + + public String getCustom2Link() { + return custom2Link; + } + + public boolean isCustom2NewWindow() { + return custom2NewWindow; + } + + public String getCustom2Enabled() { + return custom2Enabled; + } + + public String getCustom2Icon() { + return custom2Icon; + } + + public String getCustom3Link() { + return custom3Link; + } + + public boolean isCustom3NewWindow() { + return custom3NewWindow; + } + + public String getCustom3Enabled() { + return custom3Enabled; + } + + public String getCustom3Icon() { + return custom3Icon; + } + + /** + * Returns the not yet configured help plugins + * @return String[] + */ + public String[] getRemainingPlugins() { + List<String> remainingPlugins = new ArrayList<>(); + + if (!helpPluginList.contains(HelpModule.ACADEMY_KEY)) { + remainingPlugins.add(ACADEMY); + } if (!helpPluginList.contains(HelpModule.CONFLUENCE_KEY)) { + remainingPlugins.add(CONFLUENCE); + } if (!helpPluginList.contains(HelpModule.SUPPORT_KEY)) { + remainingPlugins.add(SUPPORT); + } if (!helpPluginList.contains(HelpModule.COURSE_KEY)) { + remainingPlugins.add(COURSE); + } if (!helpPluginList.contains(HelpModule.CUSTOM_1_KEY)) { + remainingPlugins.add(CUSTOM_1); + } if (!helpPluginList.contains(HelpModule.CUSTOM_2_KEY)) { + remainingPlugins.add(CUSTOM_2); + } if (!helpPluginList.contains(HelpModule.CUSTOM_3_KEY)) { + remainingPlugins.add(CUSTOM_3); + } + + return remainingPlugins.toArray(new String[remainingPlugins.size()]); + } + + // Helpers + /** + * Reloads all lists containing the help plugins for different locations + */ + private void loadLists() { + helpPluginList = new ArrayList<>(Arrays.asList(helpPlugins.split(DELIMITER))); + helpPluginList.removeAll(Arrays.asList("",null)); + + userToolHelpPlugins = new ArrayList<>(); + authorSiteHelpPlugins = new ArrayList<>(); + dmzHelpPlugins = new ArrayList<>(); + + for (String helpPlugin : Arrays.asList(helpPlugins.split(DELIMITER))) { + switch (helpPlugin) { + case ACADEMY_KEY: + if (helpPluginList.indexOf(helpPlugin) != academyPos) { + Collections.swap(helpPluginList, academyPos, helpPluginList.indexOf(helpPlugin)); + } + break; + case CONFLUENCE_KEY: + if (helpPluginList.indexOf(helpPlugin) != confluencePos) { + Collections.swap(helpPluginList, confluencePos, helpPluginList.indexOf(helpPlugin)); + } + break; + case COURSE_KEY: + if (helpPluginList.indexOf(helpPlugin) != coursePos) { + Collections.swap(helpPluginList, coursePos, helpPluginList.indexOf(helpPlugin)); + } + break; + case SUPPORT_KEY: + if (helpPluginList.indexOf(helpPlugin) != supportPos) { + Collections.swap(helpPluginList, supportPos, helpPluginList.indexOf(helpPlugin)); + } + break; + case CUSTOM_1_KEY: + if (helpPluginList.indexOf(helpPlugin) != custom1Pos) { + Collections.swap(helpPluginList, custom1Pos, helpPluginList.indexOf(helpPlugin)); + } + break; + case CUSTOM_2_KEY: + if (helpPluginList.indexOf(helpPlugin) != custom2Pos) { + Collections.swap(helpPluginList, custom2Pos, helpPluginList.indexOf(helpPlugin)); + } + break; + case CUSTOM_3_KEY: + if (helpPluginList.indexOf(helpPlugin) != custom3Pos) { + Collections.swap(helpPluginList, custom3Pos, helpPluginList.indexOf(helpPlugin)); + } + break; + + default: + break; + } + } + + for (String helpPlugin : helpPluginList) { + switch (helpPlugin) { + case ACADEMY_KEY: + AcademyLinkSPI academyHelpLinkSPI = (AcademyLinkSPI) CoreSpringFactory.getBean(helpPlugin); + if (academyEnabled.contains(USERTOOL)) { + userToolHelpPlugins.add(academyHelpLinkSPI); + } if (academyEnabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(academyHelpLinkSPI); + } if (academyEnabled.contains(DMZ)) { + dmzHelpPlugins.add(academyHelpLinkSPI); + } + break; + case CONFLUENCE_KEY: + ConfluenceLinkSPI confluenceHelpLinkSPI = (ConfluenceLinkSPI) CoreSpringFactory.getBean(helpPlugin); + if (confluenceEnabled.contains(USERTOOL)) { + userToolHelpPlugins.add(confluenceHelpLinkSPI); + } if (confluenceEnabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(confluenceHelpLinkSPI); + } if (confluenceEnabled.contains(DMZ)) { + dmzHelpPlugins.add(confluenceHelpLinkSPI); + } + break; + case COURSE_KEY: + CourseHelpSPI courseHelpLinkSPI = (CourseHelpSPI) CoreSpringFactory.getBean(helpPlugin); + if (courseEnabled.contains(USERTOOL)) { + userToolHelpPlugins.add(courseHelpLinkSPI); + } if (courseEnabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(courseHelpLinkSPI); + } if (courseEnabled.contains(DMZ)) { + dmzHelpPlugins.add(courseHelpLinkSPI); + } + break; + case SUPPORT_KEY: + SupportMailSPI supportMailHelpSPI = (SupportMailSPI) CoreSpringFactory.getBean(helpPlugin); + if (supportEnabled.contains(USERTOOL)) { + userToolHelpPlugins.add(supportMailHelpSPI); + } if (supportEnabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(supportMailHelpSPI); + } if (supportEnabled.contains(DMZ)) { + dmzHelpPlugins.add(supportMailHelpSPI); + } + break; + case CUSTOM_1_KEY: + CustomLink1SPI customLink1SPI = (CustomLink1SPI) CoreSpringFactory.getBean(helpPlugin); + if (custom1Enabled.contains(USERTOOL)) { + userToolHelpPlugins.add(customLink1SPI); + } if (custom1Enabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(customLink1SPI); + } if (custom1Enabled.contains(DMZ)) { + dmzHelpPlugins.add(customLink1SPI); + } + break; + case CUSTOM_2_KEY: + CustomLink2SPI customLink2SPI = (CustomLink2SPI) CoreSpringFactory.getBean(helpPlugin); + if (custom2Enabled.contains(USERTOOL)) { + userToolHelpPlugins.add(customLink2SPI); + } if (custom2Enabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(customLink2SPI); + } if (custom2Enabled.contains(DMZ)) { + dmzHelpPlugins.add(customLink2SPI); + } + break; + case CUSTOM_3_KEY: + CustomLink3SPI customLink3SPI = (CustomLink3SPI) CoreSpringFactory.getBean(helpPlugin); + if (custom3Enabled.contains(USERTOOL)) { + userToolHelpPlugins.add(customLink3SPI); + } if (custom3Enabled.contains(AUTHORSITE)) { + authorSiteHelpPlugins.add(customLink3SPI); + } if (custom3Enabled.contains(DMZ)) { + dmzHelpPlugins.add(customLink3SPI); + } + break; + + default: + break; + } + } + } + + /** + * Returns a string with locations where the help plugin should be displayed + * + * @param usertool + * @param authorsite + * @param login + * @return + */ + private String generateEnabledString(boolean usertool, boolean authorsite, boolean login) { + String enabled = usertool ? USERTOOL : ""; + enabled += authorsite ? "," + AUTHORSITE : ""; + enabled += login ? "," + DMZ : ""; + + return enabled; + } + + /** + * Adds a help plugin to the configuration + * + * @param plugin + */ + private void addToHelpPlugins(String plugin) { + if (!helpPluginList.contains(plugin)) { + helpPluginList.add(plugin); + } + + helpPlugins = helpPluginList.stream().collect(Collectors.joining(DELIMITER)); + setStringProperty("help.plugin", helpPlugins, true); } } \ No newline at end of file diff --git a/src/main/java/org/olat/core/commons/services/help/HelpSupportController.java b/src/main/java/org/olat/core/commons/services/help/HelpSupportController.java new file mode 100644 index 0000000000000000000000000000000000000000..1aec72216a5d0e9c5ed88340026a38f6f8e06682 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/HelpSupportController.java @@ -0,0 +1,106 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.help; + +import org.olat.admin.help.ui.HelpAdminController; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.controller.BasicController; +import org.olat.core.util.Util; +import org.olat.core.util.event.GenericEventListener; +import org.olat.core.util.mail.ContactList; +import org.olat.core.util.mail.ContactMessage; +import org.olat.modules.co.ContactFormController; +import org.springframework.beans.factory.annotation.Autowired; + +/** + * Initial Date: 27.04.2020 <br> + * + * @author aboeckle, alexander.boeckle@frentix.com, frentix GmbH, http://www.frentix.com + */ +public class HelpSupportController extends BasicController implements GenericEventListener { + + private final VelocityContainer content; + private ContactFormController contactForm; + private String contactEmail = null; + + @Autowired + private HelpModule helpModule; + + /** + * Creates this controller. + * + * @param ureq The user request. + * @param control The window control. + */ + public HelpSupportController(UserRequest ureq, WindowControl control) { + super(ureq, control); + setTranslator(Util.createPackageTranslator(HelpAdminController.class, getLocale())); + this.content = createVelocityContainer("contact"); + + // Read the destination email from the helpModule + contactEmail = helpModule.getSupportEmail(); + + ContactMessage contactMessage = new ContactMessage(ureq.getIdentity()); + ContactList contactList = new ContactList(translate("contact.to")); + + contactList.add(contactEmail); + contactMessage.addEmailTo(contactList); + + // Show GUI + contactForm = new ContactFormController(ureq, getWindowControl(), true, false, false, contactMessage); + listenTo(contactForm); + content.put("contactForm", contactForm.getInitialComponent()); + putInitialPanel(content); + } + + @Override + protected void doDispose() { + // autodispose by basic controller + } + + @Override + protected void event(UserRequest ureq, Component source, Event event) { + // Do nothing. + } + + @Override + protected void event(UserRequest ureq, Controller source, Event event) { + if (source == contactForm) { + if (event.equals(Event.CANCELLED_EVENT)) { + fireEvent(ureq, Event.CANCELLED_EVENT); + } else if(event.equals(Event.DONE_EVENT)) { + fireEvent(ureq, Event.DONE_EVENT); + + } + } + super.event(ureq, source, event); + } + + @Override + public void event(Event event) { + // nothing to do, the persisted properties used in this controller are + // read-only, no GUI to modify the properties yet + } +} diff --git a/src/main/java/org/olat/core/commons/services/help/HelpUserToolExtension.java b/src/main/java/org/olat/core/commons/services/help/HelpUserToolExtension.java index 56e7e817cf71064823c58f52ef629cad306c0f84..31399ad552df95c4255e51523c1ce3f1cdc287f9 100644 --- a/src/main/java/org/olat/core/commons/services/help/HelpUserToolExtension.java +++ b/src/main/java/org/olat/core/commons/services/help/HelpUserToolExtension.java @@ -49,7 +49,7 @@ public class HelpUserToolExtension extends UserToolExtension { @Override public UserToolCategory getUserToolCategory() { - return UserToolCategory.system; + return UserToolCategory.help; } @Override @@ -67,9 +67,7 @@ public class HelpUserToolExtension extends UserToolExtension { return null; } - HelpModule helpModule = CoreSpringFactory.getImpl(HelpModule.class); - HelpLinkSPI provider = helpModule.getHelpProvider(); - return provider.getHelpUserTool(wControl); + return super.createUserTool(ureq, wControl, locale); } @Override diff --git a/src/main/java/org/olat/core/commons/services/help/_content/contact.html b/src/main/java/org/olat/core/commons/services/help/_content/contact.html new file mode 100644 index 0000000000000000000000000000000000000000..365e2a58e98e42adcbbfbd4f4cf31229964d08fd --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/_content/contact.html @@ -0,0 +1 @@ +$r.render("contactForm") diff --git a/src/main/java/org/olat/core/commons/services/help/spi/AcademyLinkSPI.java b/src/main/java/org/olat/core/commons/services/help/spi/AcademyLinkSPI.java new file mode 100644 index 0000000000000000000000000000000000000000..411cd69751c610ee2d5e9065e54c4df78e917b14 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/spi/AcademyLinkSPI.java @@ -0,0 +1,96 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.help.spi; + +import java.util.Locale; + +import org.olat.admin.user.tools.UserTool; +import org.olat.core.commons.services.help.ConfluenceHelper; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.link.ExternalLink; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.WindowControl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 27.04.2020<br> + * @author aboeckle, alexander.boeckle@frentix.com, http://www.frentix.com + * + */ +@Service("ooAcademyLinkHelp") +public class AcademyLinkSPI implements HelpLinkSPI { + + private static final String PLUGIN_NAME = "academy"; + + @Autowired + private HelpModule helpModule; + + @Override + public UserTool getHelpUserTool(WindowControl wControl) { + return new AcademyLinkUserTool(); + } + + public class AcademyLinkUserTool implements UserTool { + + + public AcademyLinkUserTool() { + } + + @Override + public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { + ExternalLink helpLink = new ExternalLink("help.academy"); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getAcademyIcon()); + helpLink.setName(container.getTranslator().translate("help.academy")); + helpLink.setTooltip(container.getTranslator().translate("help.academy")); + helpLink.setTarget("ooAcademy"); + helpLink.setUrl(helpModule.getAcademyLink()); + container.put("help.academy", helpLink); + return helpLink; + } + + @Override + public void dispose() { + // + } + } + + @Override + public String getURL(Locale locale, String page) { + // Fallback to confluence context help + return ConfluenceHelper.getURL(locale, page); + } + + @Override + public Component getHelpPageLink(UserRequest ureq, String title, String tooltip, String iconCSS, String elementCSS, + String page) { + // Fallback to confluence context help + return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); + } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } +} diff --git a/src/main/java/org/olat/core/commons/services/help/spi/ConfluenceLinkSPI.java b/src/main/java/org/olat/core/commons/services/help/spi/ConfluenceLinkSPI.java index a94e833f8a234465eca6ebdce80cd5920a89fdf8..002ef8b2681e312c7e32b19dff73d8efb60085e0 100644 --- a/src/main/java/org/olat/core/commons/services/help/spi/ConfluenceLinkSPI.java +++ b/src/main/java/org/olat/core/commons/services/help/spi/ConfluenceLinkSPI.java @@ -24,11 +24,13 @@ import java.util.Locale; import org.olat.admin.user.tools.UserTool; import org.olat.core.commons.services.help.ConfluenceHelper; import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.link.ExternalLink; import org.olat.core.gui.components.velocity.VelocityContainer; import org.olat.core.gui.control.WindowControl; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -43,22 +45,28 @@ import org.springframework.stereotype.Service; */ @Service("ooConfluenceLinkHelp") public class ConfluenceLinkSPI implements HelpLinkSPI { + + private static final String PLUGIN_NAME = "manual"; + + @Autowired + HelpModule helpModule; + @Override public UserTool getHelpUserTool(WindowControl wControl) { return new ConfluenceUserTool(); } - + public class ConfluenceUserTool implements UserTool { @Override public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { - ExternalLink helpLink = new ExternalLink("topnav.help"); - container.put("topnav.help", helpLink); - helpLink.setIconLeftCSS("o_icon o_icon_help o_icon-lg"); - helpLink.setName(container.getTranslator().translate("topnav.help")); - helpLink.setTooltip(container.getTranslator().translate("topnav.help.alt")); + ExternalLink helpLink = new ExternalLink("help.confluence"); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getConfluenceIcon()); + helpLink.setName(container.getTranslator().translate("help.confluence")); + helpLink.setTooltip(container.getTranslator().translate("help.confluence")); helpLink.setTarget("oohelp"); helpLink.setUrl(getURL(ureq.getLocale(), null)); + container.put("help.confluence", helpLink); return helpLink; } @@ -80,4 +88,9 @@ public class ConfluenceLinkSPI implements HelpLinkSPI { // delegate to helper return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } } diff --git a/src/main/java/org/olat/core/commons/services/help/spi/HelpCourseSPI.java b/src/main/java/org/olat/core/commons/services/help/spi/CourseHelpSPI.java similarity index 82% rename from src/main/java/org/olat/core/commons/services/help/spi/HelpCourseSPI.java rename to src/main/java/org/olat/core/commons/services/help/spi/CourseHelpSPI.java index 280ef92112e7f3444968ee8b67dc2a6248ce5bfa..e65dda5e4b203a5e7b9888be4154664a1cb020f5 100644 --- a/src/main/java/org/olat/core/commons/services/help/spi/HelpCourseSPI.java +++ b/src/main/java/org/olat/core/commons/services/help/spi/CourseHelpSPI.java @@ -25,6 +25,7 @@ import org.olat.admin.user.tools.UserTool; import org.olat.core.commons.fullWebApp.popup.BaseFullWebappPopupLayoutFactory; import org.olat.core.commons.services.help.ConfluenceHelper; import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.ComponentEventListener; @@ -36,6 +37,7 @@ import org.olat.core.gui.control.Event; import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.course.CourseFactory; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** @@ -49,26 +51,31 @@ import org.springframework.stereotype.Service; * */ @Service("courseHelp") -public class HelpCourseSPI implements HelpLinkSPI { +public class CourseHelpSPI implements HelpLinkSPI { + private static final String PLUGIN_NAME = "course"; + + @Autowired + private HelpModule helpModule; + @Override public UserTool getHelpUserTool(WindowControl wControl) { - return new HelCourseUserTool(wControl); + return new HelpCourseUserTool(wControl); } - public class HelCourseUserTool implements UserTool, ComponentEventListener { + public class HelpCourseUserTool implements UserTool, ComponentEventListener { private final WindowControl wControl; - public HelCourseUserTool(WindowControl wControl) { + public HelpCourseUserTool(WindowControl wControl) { this.wControl = wControl; } @Override public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { - Link helpLink = LinkFactory.createLink("topnav.help", container, this); - helpLink.setIconLeftCSS("o_icon o_icon_help o_icon-lg"); - helpLink.setTooltip("topnav.help.alt"); + Link helpLink = LinkFactory.createLink("help.course", container, this); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getCourseIcon()); + helpLink.setTooltip("help.course"); helpLink.setTarget("oohelp"); return helpLink; } @@ -76,12 +83,13 @@ public class HelpCourseSPI implements HelpLinkSPI { @Override public void dispatchEvent(UserRequest ureq, Component source, Event event) { ControllerCreator ctrlCreator = new ControllerCreator() { + @Override public Controller createController(UserRequest lureq, WindowControl lwControl) { return CourseFactory.createHelpCourseLaunchController(lureq, lwControl); } }; //wrap the content controller into a full header layout - ControllerCreator layoutCtrlr = BaseFullWebappPopupLayoutFactory.createAuthMinimalPopupLayout(ureq, ctrlCreator); + ControllerCreator layoutCtrlr = BaseFullWebappPopupLayoutFactory.createMinimalPopupLayout(ctrlCreator); //open in new browser window wControl.getWindowBackOffice().getWindowManager() .createNewPopupBrowserWindowFor(ureq, layoutCtrlr) @@ -106,4 +114,9 @@ public class HelpCourseSPI implements HelpLinkSPI { // Fallback to confluence context help return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } } diff --git a/src/main/java/org/olat/core/commons/services/help/spi/CustomLink1SPI.java b/src/main/java/org/olat/core/commons/services/help/spi/CustomLink1SPI.java new file mode 100644 index 0000000000000000000000000000000000000000..b7670140f8f89a1c8a44a2c031d48c5b7d1c61cd --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/spi/CustomLink1SPI.java @@ -0,0 +1,95 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.help.spi; + +import java.util.Locale; + +import org.olat.admin.user.tools.UserTool; +import org.olat.core.commons.services.help.ConfluenceHelper; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.link.ExternalLink; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.WindowControl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 27.04.2020<br> + * @author aboeckle, alexander.boeckle@frentix.com, http://www.frentix.com + * + */ +@Service("customLink1Help") +public class CustomLink1SPI implements HelpLinkSPI { + + private static final String PLUGIN_NAME = "custom1"; + + @Autowired + private HelpModule helpModule; + + @Override + public UserTool getHelpUserTool(WindowControl wControl) { + return new Custom1LinkUserTool(wControl); + } + + public class Custom1LinkUserTool implements UserTool { + + public Custom1LinkUserTool(WindowControl wControl) { + } + + @Override + public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { + ExternalLink helpLink = new ExternalLink("help.custom1"); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getCustom1Icon()); + helpLink.setName(container.getTranslator().translate("help.custom1")); + helpLink.setTooltip(container.getTranslator().translate("help.custom1")); + helpLink.setTarget(helpModule.isCustom1NewWindow() ? "ooCustom1" : ""); + helpLink.setUrl(helpModule.getCustom1Link()); + container.put("help.custom1", helpLink); + return helpLink; + } + + @Override + public void dispose() { + // + } + } + + @Override + public String getURL(Locale locale, String page) { + // Fallback to confluence context help + return ConfluenceHelper.getURL(locale, page); + } + + @Override + public Component getHelpPageLink(UserRequest ureq, String title, String tooltip, String iconCSS, String elementCSS, + String page) { + // Fallback to confluence context help + return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); + } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } +} diff --git a/src/main/java/org/olat/core/commons/services/help/spi/CustomLink2SPI.java b/src/main/java/org/olat/core/commons/services/help/spi/CustomLink2SPI.java new file mode 100644 index 0000000000000000000000000000000000000000..86f91cdf3363b5a0f1a09178d923d744b581546c --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/spi/CustomLink2SPI.java @@ -0,0 +1,95 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.help.spi; + +import java.util.Locale; + +import org.olat.admin.user.tools.UserTool; +import org.olat.core.commons.services.help.ConfluenceHelper; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.link.ExternalLink; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.WindowControl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 27.04.2020<br> + * @author aboeckle, alexander.boeckle@frentix.com, http://www.frentix.com + * + */ +@Service("customLink2Help") +public class CustomLink2SPI implements HelpLinkSPI { + + private static final String PLUGIN_NAME = "custom2"; + + @Autowired + private HelpModule helpModule; + + @Override + public UserTool getHelpUserTool(WindowControl wControl) { + return new Custom2LinkUserTool(wControl); + } + + public class Custom2LinkUserTool implements UserTool { + + public Custom2LinkUserTool(WindowControl wControl) { + } + + @Override + public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { + ExternalLink helpLink = new ExternalLink("help.custom2"); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getCustom2Icon()); + helpLink.setName(container.getTranslator().translate("help.custom2")); + helpLink.setTooltip(container.getTranslator().translate("help.custom2")); + helpLink.setTarget(helpModule.isCustom2NewWindow() ? "custom2" : ""); + helpLink.setUrl(helpModule.getCustom2Link()); + container.put("help.custom2", helpLink); + return helpLink; + } + + @Override + public void dispose() { + // + } + } + + @Override + public String getURL(Locale locale, String page) { + // Fallback to confluence context help + return ConfluenceHelper.getURL(locale, page); + } + + @Override + public Component getHelpPageLink(UserRequest ureq, String title, String tooltip, String iconCSS, String elementCSS, + String page) { + // Fallback to confluence context help + return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); + } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } +} diff --git a/src/main/java/org/olat/core/commons/services/help/spi/CustomLink3SPI.java b/src/main/java/org/olat/core/commons/services/help/spi/CustomLink3SPI.java new file mode 100644 index 0000000000000000000000000000000000000000..bbeaa02c7d51a7b286db067169782b612829b666 --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/spi/CustomLink3SPI.java @@ -0,0 +1,95 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.help.spi; + +import java.util.Locale; + +import org.olat.admin.user.tools.UserTool; +import org.olat.core.commons.services.help.ConfluenceHelper; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.link.ExternalLink; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.WindowControl; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 27.04.2020<br> + * @author aboeckle, alexander.boeckle@frentix.com, http://www.frentix.com + * + */ +@Service("customLink3Help") +public class CustomLink3SPI implements HelpLinkSPI { + + private static final String PLUGIN_NAME = "custom3"; + + @Autowired + private HelpModule helpModule; + + @Override + public UserTool getHelpUserTool(WindowControl wControl) { + return new Custom3LinkUserTool(wControl); + } + + public class Custom3LinkUserTool implements UserTool { + + public Custom3LinkUserTool(WindowControl wControl) { + } + + @Override + public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { + ExternalLink helpLink = new ExternalLink("help.custom3"); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getCustom3Icon()); + helpLink.setName(container.getTranslator().translate("help.custom3")); + helpLink.setTooltip(container.getTranslator().translate("help.custom3")); + helpLink.setTarget(helpModule.isCustom3NewWindow() ? "custom3" : ""); + helpLink.setUrl(helpModule.getCustom3Link()); + container.put("help.custom3", helpLink); + return helpLink; + } + + @Override + public void dispose() { + // + } + } + + @Override + public String getURL(Locale locale, String page) { + // Fallback to confluence context help + return ConfluenceHelper.getURL(locale, page); + } + + @Override + public Component getHelpPageLink(UserRequest ureq, String title, String tooltip, String iconCSS, String elementCSS, + String page) { + // Fallback to confluence context help + return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); + } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } +} diff --git a/src/main/java/org/olat/core/commons/services/help/spi/SupportMailSPI.java b/src/main/java/org/olat/core/commons/services/help/spi/SupportMailSPI.java new file mode 100644 index 0000000000000000000000000000000000000000..78edaa391cf99f4708f6db977b354404e277b50a --- /dev/null +++ b/src/main/java/org/olat/core/commons/services/help/spi/SupportMailSPI.java @@ -0,0 +1,131 @@ +/** + * <a href="http://www.openolat.org"> + * OpenOLAT - Online Learning and Training</a><br> + * <p> + * Licensed under the Apache License, Version 2.0 (the "License"); <br> + * you may not use this file except in compliance with the License.<br> + * You may obtain a copy of the License at the + * <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache homepage</a> + * <p> + * Unless required by applicable law or agreed to in writing,<br> + * software distributed under the License is distributed on an "AS IS" BASIS, <br> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. <br> + * See the License for the specific language governing permissions and <br> + * limitations under the License. + * <p> + * Initial code contributed and copyrighted by<br> + * frentix GmbH, http://www.frentix.com + * <p> + */ +package org.olat.core.commons.services.help.spi; + +import java.util.Locale; + +import org.olat.admin.help.ui.HelpAdminController; +import org.olat.admin.user.tools.UserTool; +import org.olat.core.commons.services.help.ConfluenceHelper; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; +import org.olat.core.commons.services.help.HelpSupportController; +import org.olat.core.gui.UserRequest; +import org.olat.core.gui.components.Component; +import org.olat.core.gui.components.ComponentEventListener; +import org.olat.core.gui.components.link.Link; +import org.olat.core.gui.components.link.LinkFactory; +import org.olat.core.gui.components.velocity.VelocityContainer; +import org.olat.core.gui.control.Controller; +import org.olat.core.gui.control.ControllerEventListener; +import org.olat.core.gui.control.Event; +import org.olat.core.gui.control.WindowControl; +import org.olat.core.gui.control.generic.closablewrapper.CloseableModalController; +import org.olat.core.gui.translator.Translator; +import org.olat.core.util.Util; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + +/** + * + * Initial date: 27.04.2020<br> + * @author aboeckle, alexander.boeckle@frentix.com, http://www.frentix.com + * + */ +@Service("supportMailHelp") +public class SupportMailSPI implements HelpLinkSPI { + + private static final String PLUGIN_NAME = "mail"; + + @Autowired + private HelpModule helpModule; + + @Override + public UserTool getHelpUserTool(WindowControl wControl) { + return new SupportHelpUserTool(wControl); + } + + public class SupportHelpUserTool implements UserTool, ComponentEventListener, ControllerEventListener { + + private final WindowControl wControl; + private HelpSupportController helpSupportController; + private CloseableModalController cmc; + Translator translator; + + public SupportHelpUserTool(WindowControl wControl) { + this.wControl = wControl; + } + + @Override + public Component getMenuComponent(UserRequest ureq, VelocityContainer container) { + Link helpLink = LinkFactory.createLink("help.support", container, this); + helpLink.setIconLeftCSS("o_icon o_icon-fw " + helpModule.getSupportIcon()); + helpLink.setTooltip("help.support"); + return helpLink; + } + + @Override + public void dispatchEvent(UserRequest ureq, Component source, Event event) { + helpSupportController = new HelpSupportController(ureq, wControl); + helpSupportController.addControllerListener(this); + translator = Util.createPackageTranslator(HelpAdminController.class, ureq.getLocale()); + + cmc = new CloseableModalController(wControl, translator.translate("close"), helpSupportController.getInitialComponent(), true, translator.translate("contact"), true); + cmc.addControllerListener(this); + cmc.activate(); + } + + @Override + public void dispatchEvent(UserRequest ureq, Controller source, Event event) { + if (source == helpSupportController) { + helpSupportController.dispose(); + cmc.deactivate(); + cmc.dispose(); + } else if (source == cmc) { + helpSupportController.dispose(); + cmc.deactivate(); + cmc.dispose(); + } + } + + @Override + public void dispose() { + // + } + } + + @Override + public String getURL(Locale locale, String page) { + // Fallback to confluence context help + return ConfluenceHelper.getURL(locale, page); + } + + @Override + public Component getHelpPageLink(UserRequest ureq, String title, String tooltip, String iconCSS, String elementCSS, + String page) { + // Fallback to confluence context help + return ConfluenceHelper.createHelpPageLink(ureq, title, tooltip, iconCSS, elementCSS, page); + } + + @Override + public String getPluginName() { + return PLUGIN_NAME; + } +} diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/FormItemImpl.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/FormItemImpl.java index 344bc67e141458520b4d8bf6c970f45181a445c5..ffc9a720c5c8529bdbc5137355d8e21cf99c5919 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/FormItemImpl.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/FormItemImpl.java @@ -386,8 +386,11 @@ public abstract class FormItemImpl implements InlineElement { @Override public void setHelpUrlForManualPage(String manualAliasName) { HelpModule helpModule = CoreSpringFactory.getImpl(HelpModule.class); - Locale locale = getTranslator().getLocale(); - this.helpUrl = helpModule.getHelpProvider().getURL(locale, manualAliasName); + + if (helpModule.isManualEnabled()) { + Locale locale = getTranslator().getLocale(); + this.helpUrl = helpModule.getManualProvider().getURL(locale, manualAliasName); + } } /** diff --git a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/plugins/olatmovieviewer/OlatMovieViewerPlugin.java b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/plugins/olatmovieviewer/OlatMovieViewerPlugin.java index 8c669d1d911b958a900a2dae18781687ecad27b7..c63d9cc4dca854b71a46b78255b17029d7e33038 100644 --- a/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/plugins/olatmovieviewer/OlatMovieViewerPlugin.java +++ b/src/main/java/org/olat/core/gui/components/form/flexible/impl/elements/richText/plugins/olatmovieviewer/OlatMovieViewerPlugin.java @@ -77,7 +77,7 @@ public class OlatMovieViewerPlugin extends TinyMCECustomPlugin { String helpKey = "helpUrl" + locale.getLanguage(); if(!params.containsKey(helpKey)) { - String url = CoreSpringFactory.getImpl(HelpModule.class).getHelpProvider().getURL(locale, "Video"); + String url = CoreSpringFactory.getImpl(HelpModule.class).getManualProvider().getURL(locale, "Video"); params.put(helpKey, url); } return params; diff --git a/src/main/java/org/olat/core/gui/components/helpTooltip/HelpTooltip.java b/src/main/java/org/olat/core/gui/components/helpTooltip/HelpTooltip.java index a2f03412444f38e10f5a77755a761e96ae445c8b..ce2f7477cd01f8ad2992d4b056e6cb2eee194976 100644 --- a/src/main/java/org/olat/core/gui/components/helpTooltip/HelpTooltip.java +++ b/src/main/java/org/olat/core/gui/components/helpTooltip/HelpTooltip.java @@ -45,8 +45,8 @@ public class HelpTooltip extends AbstractComponent { static { // load help provider only once if enabled HelpModule helpModule = CoreSpringFactory.getImpl(HelpModule.class); - if (helpModule.isHelpEnabled()) { - helpProvider = helpModule.getHelpProvider(); + if (helpModule.isManualEnabled()) { + helpProvider = helpModule.getManualProvider(); } else { helpProvider = null; } diff --git a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java index 67ab5fbc5993384cd306a6c8fa0ec219b5dd937a..3eda5f14e207e3f32b9928d3b3239c847cc19ee5 100644 --- a/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java +++ b/src/main/java/org/olat/core/gui/render/velocity/VelocityRenderDecorator.java @@ -456,9 +456,9 @@ public class VelocityRenderDecorator implements Closeable { */ public StringOutput contextHelpWithWrapper(String page) { StringOutput sb = new StringOutput(192); - if (getHelpModule().isHelpEnabled()) { + if (getHelpModule().isManualEnabled()) { Locale locale = renderer.getTranslator().getLocale(); - String url = getHelpModule().getHelpProvider().getURL(locale, page); + String url = getHelpModule().getManualProvider().getURL(locale, page); if(url != null) { String title = StringHelper.escapeHtml(renderer.getTranslator().translate("help.button")); sb.append("<span class=\"o_chelp_wrapper\">") @@ -481,7 +481,7 @@ public class VelocityRenderDecorator implements Closeable { StringOutput sb = new StringOutput(100); if (getHelpModule().isHelpEnabled()) { Locale locale = renderer.getTranslator().getLocale(); - String url = getHelpModule().getHelpProvider().getURL(locale, page); + String url = getHelpModule().getManualProvider().getURL(locale, page); sb.append("contextHelpWindow('").append(url).append("')"); } return sb; @@ -498,7 +498,7 @@ public class VelocityRenderDecorator implements Closeable { public StringOutput contextHelpLink(String page) { StringOutput sb = new StringOutput(100); if (getHelpModule().isHelpEnabled()) { - String url = getHelpModule().getHelpProvider().getURL(renderer.getTranslator().getLocale(), page); + String url = getHelpModule().getManualProvider().getURL(renderer.getTranslator().getLocale(), page); sb.append(url); } return sb; @@ -652,6 +652,7 @@ public class VelocityRenderDecorator implements Closeable { * @deprecated please use escapeHtml. * @return the escaped string */ + @Deprecated public String escapeDoubleQuotes(String in) { return Formatter.escapeDoubleQuotes(in).toString(); } diff --git a/src/main/java/org/olat/course/CourseFactory.java b/src/main/java/org/olat/course/CourseFactory.java index d5392e88fcf43d4209fd929220153ec78889c541..dde0a35a26287d03121c78ac601384d90e8b5138 100644 --- a/src/main/java/org/olat/course/CourseFactory.java +++ b/src/main/java/org/olat/course/CourseFactory.java @@ -52,6 +52,7 @@ import org.olat.core.CoreSpringFactory; import org.olat.core.commons.fullWebApp.LayoutMain3ColsController; import org.olat.core.commons.modules.bc.FolderConfig; import org.olat.core.commons.persistence.DBFactory; +import org.olat.core.commons.services.help.HelpModule; import org.olat.core.commons.services.notifications.NotificationsManager; import org.olat.core.commons.services.notifications.Publisher; import org.olat.core.commons.services.notifications.SubscriptionContext; @@ -632,12 +633,17 @@ public class CourseFactory { */ public static Controller createHelpCourseLaunchController(UserRequest ureq, WindowControl wControl) { // Find repository entry for this course - String helpCourseSoftKey = CoreSpringFactory.getImpl(CourseModule.class).getHelpCourseSoftKey(); + String helpCourseSoftKey = CoreSpringFactory.getImpl(HelpModule.class).getCourseSoftkey(); RepositoryManager rm = RepositoryManager.getInstance(); RepositoryService rs = CoreSpringFactory.getImpl(RepositoryService.class); RepositoryEntry entry = null; if (StringHelper.containsNonWhitespace(helpCourseSoftKey)) { entry = rm.lookupRepositoryEntryBySoftkey(helpCourseSoftKey, false); + if (entry == null) { + try { + entry = rm.lookupRepositoryEntry(Long.valueOf(helpCourseSoftKey), false); + } catch (Exception e) {} + } } if (entry == null) { Translator translator = Util.createPackageTranslator(CourseFactory.class, ureq.getLocale()); @@ -655,6 +661,23 @@ public class CourseFactory { return new RunMainController(ureq, bwControl, null, course, entry, reSecurity, null); } } + + public static boolean isHelpCourseExisting(String helpCourseKey) { + // Find repository entry for this course + RepositoryManager rm = RepositoryManager.getInstance(); + RepositoryEntry entry = null; + + if (StringHelper.containsNonWhitespace(helpCourseKey)) { + entry = rm.lookupRepositoryEntryBySoftkey(helpCourseKey, false); + if (entry == null) { + try { + entry = rm.lookupRepositoryEntry(Long.valueOf(helpCourseKey), false); + } catch (Exception e) {} + } + } + + return entry != null; + } /** * visit all nodes in the specified course and make them archiving any data diff --git a/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java b/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java index fc9264a4468d3e39843363e5bca0e56ddd093026..b143dbc958854561cd8c61e285a5978b8d3ee8b4 100644 --- a/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java +++ b/src/main/java/org/olat/course/nodes/gta/ui/GTAWorkflowEditController.java @@ -513,7 +513,7 @@ public class GTAWorkflowEditController extends FormBasicController { private void doConfirmChanges(UserRequest ureq) { String title = translate("warning.tasks.in.process.title"); - String url = helpModule.getHelpProvider().getURL(getLocale(), "Task - Further Configurations#_concurrent_edits"); + String url = helpModule.getManualProvider().getURL(getLocale(), "Task - Further Configurations#_concurrent_edits"); String text = translate("warning.tasks.in.process.text", new String[]{ url }); confirmChangesCtrl = activateOkCancelDialog(ureq, title, text, confirmChangesCtrl); } diff --git a/src/main/java/org/olat/gui/control/OlatDmzTopNavController.java b/src/main/java/org/olat/gui/control/OlatDmzTopNavController.java index c6cea742faba2e728b888b58c8246a118fa52366..ff454148af8ba5dcf139060193e25094f26d1f65 100644 --- a/src/main/java/org/olat/gui/control/OlatDmzTopNavController.java +++ b/src/main/java/org/olat/gui/control/OlatDmzTopNavController.java @@ -24,6 +24,10 @@ */ package org.olat.gui.control; +import java.util.ArrayList; +import java.util.List; + +import org.olat.admin.help.ui.HelpAdminController; import org.olat.core.commons.chiefcontrollers.LanguageChooserController; import org.olat.core.commons.controllers.impressum.ImpressumDmzMainController; import org.olat.core.commons.controllers.impressum.ImpressumInformations; @@ -43,6 +47,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; +import org.olat.core.util.Util; import org.olat.core.util.i18n.I18nModule; import org.olat.login.AboutController; import org.springframework.beans.factory.annotation.Autowired; @@ -64,6 +69,9 @@ public class OlatDmzTopNavController extends BasicController implements Lockable public OlatDmzTopNavController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); + // Add translator for help plugins + setTranslator(Util.createPackageTranslator(HelpAdminController.class, getLocale(), getTranslator())); + VelocityContainer vc = createVelocityContainer("dmztopnav"); // impressum @@ -77,12 +85,11 @@ public class OlatDmzTopNavController extends BasicController implements Lockable // help on login page if (helpModule.isHelpEnabled()) { - HelpLinkSPI provider = helpModule.getHelpProvider(); - Component helpLink = provider.getHelpPageLink(ureq, translate("topnav.help"), translate("topnav.help.alt"), "o_icon o_icon-wf o_icon_help", null, "Login Page"); - vc.put("topnav.help", helpLink); - - Component browsercheckLink = provider.getHelpPageLink(ureq, translate("topnav.check"), translate("topnav.check.alt"), "o_icon o_icon-wf o_icon_browsercheck", null, "Login Page#login_browsercheck"); - vc.put("topnav.browsercheck", browsercheckLink); + List<String> helpPlugins = new ArrayList<>(); + for (HelpLinkSPI helpLinkSPI : helpModule.getDMZHelpPlugins()) { + helpPlugins.add(helpLinkSPI.getHelpUserTool(getWindowControl()).getMenuComponent(ureq, vc).getComponentName()); + } + vc.contextPut("helpPlugins", helpPlugins); } // about link aboutLink = AboutController.aboutLinkFactory("top.menu.about", getLocale(), this, true, false); diff --git a/src/main/java/org/olat/gui/control/OlatGuestTopNavController.java b/src/main/java/org/olat/gui/control/OlatGuestTopNavController.java index 646e40f4b2bd92e01b282bd26ece652d6f9883ba..356e8ff03de2607e0ae4dfdaa3d100bce5756356 100644 --- a/src/main/java/org/olat/gui/control/OlatGuestTopNavController.java +++ b/src/main/java/org/olat/gui/control/OlatGuestTopNavController.java @@ -25,6 +25,9 @@ package org.olat.gui.control; +import java.util.ArrayList; +import java.util.List; + import org.olat.admin.user.tools.UserTool; import org.olat.basesecurity.AuthHelper; import org.olat.core.CoreSpringFactory; @@ -46,6 +49,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.gui.control.creator.ControllerCreator; import org.olat.core.gui.control.generic.popup.PopupBrowserWindow; +import org.olat.gui.control.OlatTopNavController.Tool; import org.olat.search.SearchModule; import org.olat.search.SearchUserToolExtension; import org.springframework.beans.factory.annotation.Autowired; @@ -88,9 +92,18 @@ public class OlatGuestTopNavController extends BasicController implements Lockab // the help link HelpModule helpModule = CoreSpringFactory.getImpl(HelpModule.class); if (helpModule.isHelpEnabled()) { - HelpLinkSPI provider = helpModule.getHelpProvider(); - UserTool tool = provider.getHelpUserTool(getWindowControl()); - tool.getMenuComponent(ureq, vc); + List<Tool> helpPluginLinksName = new ArrayList<>(); + for (HelpLinkSPI helpLinkSPI : helpModule.getDMZHelpPlugins()) { + UserTool helpTool = helpLinkSPI.getHelpUserTool(getWindowControl()); + if (helpTool != null) { + Component cmp = helpTool.getMenuComponent(ureq, vc); + String CssId = "o_navbar_help_" + helpLinkSPI.getPluginName(); + String cssClass = ""; + helpPluginLinksName.add(new Tool(CssId, cssClass, cmp.getComponentName())); + } + } + + vc.contextPut("helpPlugins", helpPluginLinksName); } loginLink = LinkFactory.createLink("topnav.login", vc, this); @@ -126,8 +139,9 @@ public class OlatGuestTopNavController extends BasicController implements Lockab } } + @Override protected void doDispose() { // controllers disposed by BasicController: } -} +} \ No newline at end of file diff --git a/src/main/java/org/olat/gui/control/OlatTopNavController.java b/src/main/java/org/olat/gui/control/OlatTopNavController.java index aab19d786160359b776b338974d2f705d586f19f..165c88dddddde99d8dd69ba46d1fd613dfb01dcb 100644 --- a/src/main/java/org/olat/gui/control/OlatTopNavController.java +++ b/src/main/java/org/olat/gui/control/OlatTopNavController.java @@ -25,9 +25,12 @@ import java.util.List; import java.util.Set; import org.olat.admin.user.tools.UserTool; +import org.olat.admin.user.tools.UserToolCategory; import org.olat.admin.user.tools.UserToolExtension; import org.olat.admin.user.tools.UserToolsModule; import org.olat.core.commons.fullWebApp.LockableController; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; import org.olat.core.dispatcher.DispatcherModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; @@ -61,6 +64,8 @@ public class OlatTopNavController extends BasicController implements LockableCon @Autowired private UserToolsModule userToolsModule; + @Autowired + private HelpModule helpModule; public OlatTopNavController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); @@ -127,6 +132,7 @@ public class OlatTopNavController extends BasicController implements LockableCon private void loadPersonalTools(UserRequest ureq) { List<Tool> toolSetLinksName = new ArrayList<>(); + List<Tool> helpPluginLinksName = new ArrayList<>(); Preferences prefs = ureq.getUserSession().getGuiPreferences(); String selectedTools = userToolsModule.getUserTools(prefs); @@ -147,15 +153,30 @@ public class OlatTopNavController extends BasicController implements LockableCon if(toolExtension.isShortCutOnly() || selectedToolSet.contains(toolExtension.getUniqueExtensionID())) { UserTool tool = toolExtension.createUserTool(ureq, getWindowControl(), getLocale()); if(tool != null) { - Component cmp = tool.getMenuComponent(ureq, topNavVC); - String cssId = toolExtension.getShortCutCssId(); - String cssClass = toolExtension.getShortCutCssClass(); - toolSetLinksName.add(new Tool(cssId, cssClass, cmp.getComponentName())); - disposableTools.add(tool); + if (toolExtension.getUserToolCategory().equals(UserToolCategory.help)) { + for (HelpLinkSPI helpLinkSPI : helpModule.getUserToolHelpPlugins()) { + UserTool helpTool = helpLinkSPI.getHelpUserTool(getWindowControl()); + if (helpTool != null) { + Component cmp = helpTool.getMenuComponent(ureq, topNavVC); + String CssId = toolExtension.getShortCutCssId() + "_" + helpLinkSPI.getPluginName(); + String cssClass = toolExtension.getShortCutCssClass(); + helpPluginLinksName.add(new Tool(CssId, cssClass, cmp.getComponentName())); + disposableTools.add(helpTool); + } + } + } else { + Component cmp = tool.getMenuComponent(ureq, topNavVC); + String cssId = toolExtension.getShortCutCssId(); + String cssClass = toolExtension.getShortCutCssClass(); + toolSetLinksName.add(new Tool(cssId, cssClass, cmp.getComponentName())); + disposableTools.add(tool); + } + } } } topNavVC.contextPut("toolSet", toolSetLinksName); + topNavVC.contextPut("helpPlugins", helpPluginLinksName); } @Override diff --git a/src/main/java/org/olat/gui/control/UserToolsMenuController.java b/src/main/java/org/olat/gui/control/UserToolsMenuController.java index 705b1fd1bc1de67c7dcf3deeeee5a0ed805b9fcf..c1b0fbc5550f8f2d5a6ab2216dba13efcef86f64 100644 --- a/src/main/java/org/olat/gui/control/UserToolsMenuController.java +++ b/src/main/java/org/olat/gui/control/UserToolsMenuController.java @@ -24,12 +24,15 @@ import java.util.HashSet; import java.util.List; import java.util.Set; +import org.olat.admin.help.ui.HelpAdminController; import org.olat.admin.user.tools.UserTool; import org.olat.admin.user.tools.UserToolCategory; import org.olat.admin.user.tools.UserToolExtension; import org.olat.admin.user.tools.UserToolsModule; import org.olat.basesecurity.AuthHelper; import org.olat.core.commons.fullWebApp.LockableController; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.velocity.VelocityContainer; @@ -39,6 +42,7 @@ import org.olat.core.gui.control.WindowControl; import org.olat.core.gui.control.controller.BasicController; import org.olat.core.util.StringHelper; import org.olat.core.util.UserSession; +import org.olat.core.util.Util; import org.olat.core.util.prefs.Preferences; import org.springframework.beans.factory.annotation.Autowired; @@ -57,10 +61,14 @@ public class UserToolsMenuController extends BasicController implements Lockable @Autowired private UserToolsModule userToolsModule; + @Autowired + private HelpModule helpModule; public UserToolsMenuController(UserRequest ureq, WindowControl wControl) { super(ureq, wControl); + setTranslator(Util.createPackageTranslator(HelpAdminController.class, getLocale(), getTranslator())); + menuVC = createVelocityContainer("menu"); menuVC.setDomReplacementWrapperRequired(false); if(ureq.getIdentity() != null) { @@ -82,6 +90,7 @@ public class UserToolsMenuController extends BasicController implements Lockable List<String> configLinksName = new ArrayList<>(); List<String> searchLinksName = new ArrayList<>(); List<String> systemLinksName = new ArrayList<>(); + List<String> helpLinksName = new ArrayList<>(); Preferences prefs = ureq.getUserSession().getGuiPreferences(); String selectedTools = userToolsModule.getUserTools(prefs); @@ -111,12 +120,27 @@ public class UserToolsMenuController extends BasicController implements Lockable case personal: linksName.add(linkName); break; case config: configLinksName.add(linkName); break; case system: systemLinksName.add(linkName); break; + case help: + // Load help plugins + for (HelpLinkSPI helpLinkSPI : helpModule.getUserToolHelpPlugins()) { + UserTool helpTool = helpLinkSPI.getHelpUserTool(getWindowControl()); + if (helpTool != null) { + Component helpLink = helpTool.getMenuComponent(ureq, menuVC); + String helpLinkName = helpLink.getComponentName(); + + helpLinksName.add(helpLinkName); + + disposableTools.add(helpTool); + } + } + break; } disposableTools.add(tool); } } } + menuVC.contextPut("helpPlugins", helpLinksName); menuVC.contextPut("personalTools", linksName); menuVC.contextPut("configs", configLinksName); menuVC.contextPut("systems", systemLinksName); diff --git a/src/main/java/org/olat/gui/control/_content/dmztopnav.html b/src/main/java/org/olat/gui/control/_content/dmztopnav.html index d343b97c75988ba0d76d7749d274915254f0c1e2..b6aa0f7de580ccdb40fdb75fff1a821f4abe92e9 100644 --- a/src/main/java/org/olat/gui/control/_content/dmztopnav.html +++ b/src/main/java/org/olat/gui/control/_content/dmztopnav.html @@ -8,14 +8,11 @@ <i class="o_icon o_icon_help o_icon-lg"></i> $r.translate("topnav.help") </a> <ul class="dropdown-menu dropdown-menu-right"> - #if($r.available("topnav.help")) - <li id="o_navbar_help"> - $r.render("topnav.help") - </li> - <li> - $r.render("topnav.browsercheck") - </li> - #end + #if($helpPlugins && $helpPlugins.size() > 0) + #foreach($helpPlugin in $helpPlugins) + <li>$r.render($helpPlugin)</li> + #end + #end <li id="o_navbar_about"> $r.render("topnav.about") </li> diff --git a/src/main/java/org/olat/gui/control/_content/guesttopnav.html b/src/main/java/org/olat/gui/control/_content/guesttopnav.html index e3650e7ac3a76232e77f1738ff2134c5f65c643a..de961530b5268d1feb465b53afb0434b1e1d55fb 100644 --- a/src/main/java/org/olat/gui/control/_content/guesttopnav.html +++ b/src/main/java/org/olat/gui/control/_content/guesttopnav.html @@ -16,10 +16,24 @@ $r.render("search.tool") </li> #end - #if($r.available("topnav.help")) - <li id="o_navbar_help"> - $r.render("topnav.help") - </li> + #if($helpPlugins) + #if($helpPlugins.size() == 1) + #foreach($helpPlugin in $helpPlugins) + <li #if($helpPlugin.shortCutCssId) id="$helpPlugin.shortCutCssId" #end class="o_navbar_tool #if($helpPlugin.shortCutCssClass) $helpPlugin.shortCutCssClass #end">$r.render($helpPlugin.shortCutComponentName)</li> + #end + #elseif($helpPlugins.size() > 1) + <li id="o_navbar_help_opener" class="o_navbar_tool dropdown"> + <a id="o_help_tool_toggler" href="#" class="dropdown-toggle" data-toggle="dropdown" title="$r.translate("search")" aria-label="$r.translate("search")"> + <i class="o_icon o_icon_help o_icon-lg"></i> + <span>$r.translate("topnav.search")</span> + </a> + <ul class="dropdown-menu dropdown-menu-right"> + #foreach($helpPlugin in $helpPlugins) + <li #if($helpPlugin.shortCutCssId) id="$helpPlugin.shortCutCssId" #end class="o_navbar_tool #if($helpPlugin.shortCutCssClass) $helpPlugin.shortCutCssClass #end">$r.render($helpPlugin.shortCutComponentName)</li> + #end + </ul> + </li> + #end #end <li id="o_navbar_login"> $r.render("topnav.login") diff --git a/src/main/java/org/olat/gui/control/_content/menu.html b/src/main/java/org/olat/gui/control/_content/menu.html index dda28eb404b9fdf0e1850e105190396247046cb8..c1e475c54e652ee3b0c3d6214a7d6bf63227c7f0 100644 --- a/src/main/java/org/olat/gui/control/_content/menu.html +++ b/src/main/java/org/olat/gui/control/_content/menu.html @@ -17,6 +17,13 @@ <li>$r.render($config)</li> #end #end + #if($helpPlugins && $helpPlugins.size() > 0) + <li role="presentation" class="divider"></li> + <li role="presentation" class="dropdown-header">$r.translate("topnav.my.menu.help")</li> + #foreach($helpPlugin in $helpPlugins) + <li>$r.render($helpPlugin)</li> + #end + #end #if($systems && $systems.size() > 0) <li role="presentation" class="divider"></li> <li role="presentation" class="dropdown-header">$r.translate("topnav.my.menu.systems")</li> diff --git a/src/main/java/org/olat/gui/control/_content/print.html b/src/main/java/org/olat/gui/control/_content/print.html index 0456790fce33686b98253667e82d0acc6b778592..c2d4245c7c21b2b75192328003cd1fe4f0004757 100644 --- a/src/main/java/org/olat/gui/control/_content/print.html +++ b/src/main/java/org/olat/gui/control/_content/print.html @@ -1,4 +1,4 @@ <a href="javascript:o_doPrint();" title="$r.translateInAttribute("topnav.printview.alt")" > - <i class="o_icon o_icon_print o_icon-lg"></i> + <i class="o_icon o_icon_print o_icon-fw"></i> <span>$r.translate("topnav.printview")</span> </a> \ No newline at end of file diff --git a/src/main/java/org/olat/gui/control/_content/topnav.html b/src/main/java/org/olat/gui/control/_content/topnav.html index 17de5981abc86cbd614d7ff86d92fa2f0bf20b5e..b09dd1bdfe07b95bf8d180f1c26142be146859fd 100644 --- a/src/main/java/org/olat/gui/control/_content/topnav.html +++ b/src/main/java/org/olat/gui/control/_content/topnav.html @@ -4,6 +4,25 @@ #foreach($personalTool in $toolSet) <li #if($personalTool.shortCutCssId) id="$personalTool.shortCutCssId" #end class="o_navbar_tool #if($personalTool.shortCutCssClass) $personalTool.shortCutCssClass #end">$r.render($personalTool.shortCutComponentName)</li> #end + #if($helpPlugins) + #if($helpPlugins.size() == 1) + #foreach($helpPlugin in $helpPlugins) + <li #if($helpPlugin.shortCutCssId) id="$helpPlugin.shortCutCssId" #end class="o_navbar_tool #if($helpPlugin.shortCutCssClass) $helpPlugin.shortCutCssClass #end">$r.render($helpPlugin.shortCutComponentName)</li> + #end + #elseif($helpPlugins.size() > 1) + <li id="o_navbar_help_opener" class="o_navbar_tool dropdown"> + <a id="o_help_tool_toggler" href="#" class="dropdown-toggle" data-toggle="dropdown" title="$r.translate("search")" aria-label="$r.translate("search")"> + <i class="o_icon o_icon_help o_icon-lg"></i> + <span>$r.translate("topnav.search")</span> + </a> + <ul class="dropdown-menu dropdown-menu-right"> + #foreach($helpPlugin in $helpPlugins) + <li #if($helpPlugin.shortCutCssId) id="$helpPlugin.shortCutCssId" #end class="o_navbar_tool #if($helpPlugin.shortCutCssClass) $helpPlugin.shortCutCssClass #end">$r.render($helpPlugin.shortCutComponentName)</li> + #end + </ul> + </li> + #end + #end #end #if (!$isGuest && !$isInvitee) <li id="o_navbar_my_menu" class="o_portrait"> @@ -20,3 +39,12 @@ #end </ul> </div> + +## focus search input field whenever search is displayed +<script> +jQuery('#o_help_tool_toggler').click(function () { + setTimeout(function() { + jQuery('#o_help_tool_toggler[aria-expanded="true"] + .dropdown-menu #o_navbar_help_list input:text').focus(); + },0); +}); +</script> diff --git a/src/main/java/org/olat/gui/control/_i18n/LocalStrings_de.properties b/src/main/java/org/olat/gui/control/_i18n/LocalStrings_de.properties index e8d46972c7c8bae88aacf944a06e4845654af760..ceb5cb6190aa2187235f1566281fc4346a4b21c4 100644 --- a/src/main/java/org/olat/gui/control/_i18n/LocalStrings_de.properties +++ b/src/main/java/org/olat/gui/control/_i18n/LocalStrings_de.properties @@ -1,6 +1,6 @@ -#Wed Nov 04 23:14:08 CET 2015 - +#Tue May 12 07:28:00 CEST 2020 command.closeprinting=Druckansicht schliessen +contact.to=Support footer.ajax.hover=AJAX-Modus ist eingeschaltet\: Damit sind Sie schnell in OLAT unterwegs. footer.login=Login logged.in.invitee=(eingeladen) @@ -19,6 +19,7 @@ topnav.login.alt=Loggen Sie sich in OLAT ein topnav.logout=Log out topnav.logout.alt=Loggen Sie sich aus OLAT aus topnav.my.menu.configurations=Konfiguration +topnav.my.menu.help=Hilfe topnav.my.menu.label={0} topnav.my.menu.systems=System topnav.my.menu.tools=Pers\u00F6nliche Werkzeuge diff --git a/src/main/java/org/olat/gui/control/_i18n/LocalStrings_en.properties b/src/main/java/org/olat/gui/control/_i18n/LocalStrings_en.properties index 5af33cfcd126236ae73a512034f31510cf9bed89..10bd2e684609fbc5720d5c171e9e70c3066b3193 100644 --- a/src/main/java/org/olat/gui/control/_i18n/LocalStrings_en.properties +++ b/src/main/java/org/olat/gui/control/_i18n/LocalStrings_en.properties @@ -1,6 +1,6 @@ -#Wed Nov 04 23:14:08 CET 2015 - +#Tue May 12 07:28:00 CEST 2020 command.closeprinting=Close print view +contact.to=Support footer.ajax.hover=AJAX mode is active--which means faster action in OLAT. footer.login=Login logged.in.invitee=(invited) @@ -19,6 +19,7 @@ topnav.login.alt=Log in to OLAT topnav.logout=Log out topnav.logout.alt=Log off from OLAT topnav.my.menu.configurations=Configuration +topnav.my.menu.help=Help topnav.my.menu.label={0} topnav.my.menu.systems=System topnav.my.menu.tools=Personal tools diff --git a/src/main/java/org/olat/ims/cp/ui/CPContentController.java b/src/main/java/org/olat/ims/cp/ui/CPContentController.java index d5cd1a0b2b7b0fad2b6a1b73475edaab60d3cc29..a0eb70c9497870da68565e09dd04eb18413eab43 100644 --- a/src/main/java/org/olat/ims/cp/ui/CPContentController.java +++ b/src/main/java/org/olat/ims/cp/ui/CPContentController.java @@ -88,7 +88,7 @@ public class CPContentController extends BasicController { // init help link, can't do this in initToolbar because ureq is missing if (helpModule.isHelpEnabled()) { - HelpLinkSPI provider = helpModule.getHelpProvider(); + HelpLinkSPI provider = helpModule.getManualProvider(); helpLink = provider.getHelpPageLink(ureq, translate("help"), translate("helpbutton"), "o_icon o_icon-lg o_icon_help", null, "CP Editor"); } diff --git a/src/main/java/org/olat/repository/ui/author/AuthorListController.java b/src/main/java/org/olat/repository/ui/author/AuthorListController.java index 3e3fb491bc87481ac23b41fb2d1e5005b553265d..4087f59c6f85504ed7a045271fe58f5f502a4dbd 100644 --- a/src/main/java/org/olat/repository/ui/author/AuthorListController.java +++ b/src/main/java/org/olat/repository/ui/author/AuthorListController.java @@ -26,6 +26,7 @@ import java.util.Set; import java.util.concurrent.atomic.AtomicInteger; import org.olat.NewControllerFactory; +import org.olat.admin.help.ui.HelpAdminController; import org.olat.admin.user.UserSearchController; import org.olat.basesecurity.GroupRoles; import org.olat.basesecurity.OrganisationRoles; @@ -33,6 +34,8 @@ import org.olat.basesecurity.events.MultiIdentityChosenEvent; import org.olat.basesecurity.events.SingleIdentityChosenEvent; import org.olat.core.commons.persistence.DB; import org.olat.core.commons.persistence.SortKey; +import org.olat.core.commons.services.help.HelpLinkSPI; +import org.olat.core.commons.services.help.HelpModule; import org.olat.core.commons.services.license.LicenseModule; import org.olat.core.commons.services.license.ui.LicenseRenderer; import org.olat.core.commons.services.mark.Mark; @@ -41,6 +44,7 @@ import org.olat.core.gui.UserRequest; import org.olat.core.gui.components.Component; import org.olat.core.gui.components.dropdown.Dropdown; import org.olat.core.gui.components.dropdown.Dropdown.Spacer; +import org.olat.core.gui.components.dropdown.DropdownOrientation; import org.olat.core.gui.components.form.flexible.FormItem; import org.olat.core.gui.components.form.flexible.FormItemContainer; import org.olat.core.gui.components.form.flexible.elements.FlexiTableElement; @@ -205,6 +209,8 @@ public class AuthorListController extends FormBasicController implements Activat private RepositoryEntryLicenseHandler licenseHandler; @Autowired private LearningPathService learningPathService; + @Autowired + private HelpModule helpModule; public AuthorListController(UserRequest ureq, WindowControl wControl, String i18nName, SearchAuthorRepositoryEntryViewParams searchParams, boolean withSearch, boolean withClosedfilter) { @@ -264,6 +270,27 @@ public class AuthorListController extends FormBasicController implements Activat } } stackPanel.addTool(createDropdown, Align.left); + + // Help module + if (helpModule.isHelpEnabled()) { + VelocityContainer helpVC = createVelocityContainer("help"); + helpVC.setTranslator(Util.createPackageTranslator(HelpAdminController.class, getLocale())); + List<HelpLinkSPI> helpLinks = helpModule.getAuthorSiteHelpPlugins(); + + if (helpLinks.size() == 1) { + stackPanel.addTool(helpLinks.get(0).getHelpUserTool(getWindowControl()).getMenuComponent(ureq, helpVC), Align.right); + } else if (helpLinks.size() > 1) { + Dropdown helpDropdown = new Dropdown("help.list", "help.authoring", false, Util.createPackageTranslator(HelpAdminController.class, getLocale())); + helpDropdown.setIconCSS("o_icon o_icon_help"); + helpDropdown.setOrientation(DropdownOrientation.right); + + for (HelpLinkSPI helpLinkSPI : helpLinks) { + helpDropdown.addComponent(helpLinkSPI.getHelpUserTool(getWindowControl()).getMenuComponent(ureq, helpVC)); + } + + stackPanel.addTool(helpDropdown, Align.right); + } + } } } diff --git a/src/main/resources/serviceconfig/olat.properties b/src/main/resources/serviceconfig/olat.properties index 27ae707907e3d28d6ba3e6a1ef2d91d133ac2490..f784192cfa69a53a0f3690a9b690ed380a972676 100644 --- a/src/main/resources/serviceconfig/olat.properties +++ b/src/main/resources/serviceconfig/olat.properties @@ -423,11 +423,34 @@ certificate.linemanager=false # your own help plugin and configure it here. help.enabled=true # Define the plugin which generate the help URL -help.plugin=ooConfluenceLinkHelp -help.plugin.values=ooConfluenceLinkHelp,courseHelp +help.plugin=ooConfluenceLinkHelp,ooAcademyLinkHelp +help.plugin.values=ooConfluenceLinkHelp,ooAcademyLinkHelp,supportMailHelp,courseHelp,customLink1Help,customLink2Help +# Note that when you use anything but ooConfluenceLinkHelp, the context help will be disabled. Only the help button in the top navigation will be available and open the help course + +# Settings for the ooConfluenceLinkHelp plugin +help.confluence.enabled=usertool,authorsite,dmz +help.confluence.icon=o_icon_manual + +# Settings for the ooAcademyLinkHelp plugin +help.academy.link=https://www.openolat.com/openolat-academy/ +help.academy.enabled=usertool,authorsite,dmz +help.academy.icon=o_icon_video + +# Settings for the supportMailHelp plugin +help.support.email=${supportemail} +help.support.enabled=usertool,authorsite,dmz + # Settings for the courseHelp plugin -# Note that when you use courseHelp, the context help will be disabled. Only the help button in the top navigation will be available and open the help course help.course.softkey=OLAT::help-course_de.zip +help.course.enabled= + +# Settings for the customLinkHelp plugin +help.custom1.link= +help.custom1.enabled= +help.custom2.link= +help.custom2.enabled= +help.custom3.link= +help.custom3.enabled= ######################################################################## # OLAT technical settings