From b610f9258ce798bc90046440469b410e142e021e Mon Sep 17 00:00:00 2001 From: Jens Pelzetter Date: Sat, 28 Nov 2020 17:53:01 +0100 Subject: [PATCH] Applications administration, Shortcuts administration --- ccm-bundle-devel-wildfly/pom.xml | 8 ++ .../src/main/resources/log4j2.xml | 6 ++ .../libreccm/ui/admin/AdminApplication.java | 20 ++-- .../applications/ApplicationTypeInfoItem.java | 2 +- .../applications/ApplicationsController.java | 61 ++++-------- .../admin/applications/ApplicationsPage.java | 29 ++++-- ...java => DefaultApplicationController.java} | 33 +++---- .../org/libreccm/web/ApplicationType.java | 5 + .../components/bootstrap/formGroupText.xhtml | 1 + .../admin/applications/applicationtypes.xhtml | 21 +++-- .../categories/categorysystem-details.xhtml | 4 +- .../org/libreccm/shortcuts/Shortcuts.java | 27 +++--- .../ShortcutsApplicationController.java | 80 +++++++++++++++- .../applications/shortcuts/shortcuts.xhtml | 92 +++++++++++++++---- .../shortcuts/ShortcutsResources.properties | 17 ++++ .../ShortcutsResources_de.properties | 17 ++++ 16 files changed, 294 insertions(+), 129 deletions(-) rename ccm-core/src/main/java/org/libreccm/ui/admin/applications/{IsApplicationControllerFor.java => DefaultApplicationController.java} (66%) diff --git a/ccm-bundle-devel-wildfly/pom.xml b/ccm-bundle-devel-wildfly/pom.xml index e936bc880..1cdb1c0f4 100644 --- a/ccm-bundle-devel-wildfly/pom.xml +++ b/ccm-bundle-devel-wildfly/pom.xml @@ -216,6 +216,14 @@ WEB-INF/ + + org.libreccm + ccm-shortcuts + jar + + WEB-INF/ + + org.libreccm ccm-core diff --git a/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml b/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml index ad3d929fb..e5dac78bf 100644 --- a/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml +++ b/ccm-bundle-devel-wildfly/src/main/resources/log4j2.xml @@ -101,5 +101,11 @@ + + + + diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/AdminApplication.java b/ccm-core/src/main/java/org/libreccm/ui/admin/AdminApplication.java index 193aee0e1..3afdaeb16 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/AdminApplication.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/AdminApplication.java @@ -18,9 +18,12 @@ */ package org.libreccm.ui.admin; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.libreccm.ui.IsAuthenticatedFilter; import java.util.HashSet; +import java.util.Objects; import java.util.Set; import java.util.stream.Collectors; @@ -32,12 +35,16 @@ import javax.ws.rs.core.Application; /** * Collects the controllers for the admin application and registers them with * JAX-RS. - * + * * @author Jens Pelzetter */ @ApplicationPath("/@admin") public class AdminApplication extends Application { + private static final Logger LOGGER = LogManager.getLogger( + AdminApplication.class + ); + /** * Injection point for the admin pages. */ @@ -49,7 +56,7 @@ public class AdminApplication extends Application { final Set> classes = new HashSet<>(); classes.add(IsAuthenticatedFilter.class); - + classes.addAll( adminPages .stream() @@ -58,12 +65,11 @@ public class AdminApplication extends Application { .collect(Collectors.toSet()) ); - return classes; + LOGGER.debug( + "Adding classes to AdminApplication: {}", Objects.toString(classes) + ); -// final Set> classes = new HashSet<>(); -// classes.add(SystemInformationController.class); -//// classes.add(UsersApi.class); -// return classes; + return classes; } } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java index b598f9e66..862171648 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationTypeInfoItem.java @@ -36,7 +36,7 @@ public class ApplicationTypeInfoItem implements private boolean singleton; private long numberOfInstances; - + private String controllerLink; protected ApplicationTypeInfoItem() { diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java index 531abaf94..b94ec271c 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsController.java @@ -32,13 +32,11 @@ import java.util.Map; import java.util.stream.Collectors; import javax.enterprise.context.RequestScoped; -import javax.enterprise.inject.Any; -import javax.enterprise.inject.Instance; -import javax.enterprise.util.AnnotationLiteral; import javax.inject.Inject; import javax.mvc.Controller; import javax.mvc.Models; import javax.mvc.MvcContext; +import javax.transaction.Transactional; import javax.ws.rs.GET; import javax.ws.rs.Path; @@ -63,17 +61,14 @@ public class ApplicationsController { @Inject private Models models; - @Inject - private MvcContext mvc; - - @Inject - @Any - private Instance applicationControllers; +// @Inject +// private MvcContext mvc; @GET @Path("/") @AuthorizationRequired @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) public String getApplicationTypes() { final List appTypes = appManager .getApplicationTypes() @@ -104,46 +99,26 @@ public class ApplicationsController { appRepository.findByType(applicationType.name()).size() ); - final IsApplicationControllerForLiteral literal - = new IsApplicationControllerForLiteral(applicationType.name()); + final Class controllerClass + = applicationType.applicationController(); - final Instance instance = applicationControllers - .select(literal); - - if (instance.isResolvable()) { - final ApplicationController controller = instance.get(); + if (!DefaultApplicationController.class + .isAssignableFrom(controllerClass)) { +// item.setControllerLink( +// mvc.uri( +// String.format( +// "%s#getApplication", controllerClass.getSimpleName() +// ) +// ).toString() +// ); item.setControllerLink( - mvc.uri( - String.format( - "%s#getApplication", - controller.getClass().getSimpleName() - ) - ).toString() + String.format( + "%s#getApplication", + controllerClass.getSimpleName()) ); } return item; } - private class IsApplicationControllerForLiteral - extends AnnotationLiteral - implements IsApplicationControllerFor { - - private static final long serialVersionUID = 1L; - - private final String value; - - public IsApplicationControllerForLiteral( - final String value - ) { - this.value = value; - } - - @Override - public String value() { - return value; - } - - } - } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java index 04ea09731..d55460afb 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/ApplicationsPage.java @@ -18,15 +18,17 @@ */ package org.libreccm.ui.admin.applications; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import org.libreccm.ui.admin.AdminConstants; import org.libreccm.ui.admin.AdminPage; +import org.libreccm.web.ApplicationManager; import java.util.HashSet; import java.util.Set; +import java.util.stream.Collectors; import javax.enterprise.context.ApplicationScoped; -import javax.enterprise.inject.Any; -import javax.enterprise.inject.Instance; import javax.inject.Inject; /** @@ -35,21 +37,28 @@ import javax.inject.Inject; */ @ApplicationScoped public class ApplicationsPage implements AdminPage { + + private static final Logger LOGGER = LogManager.getLogger( + ApplicationsPage.class + ); @Inject - @Any - private Instance applicationControllers; - + private ApplicationManager applicationManager; + @Override public Set> getControllerClasses() { final Set> classes = new HashSet<>(); classes.add(ApplicationsController.class); - applicationControllers - .stream() - .map(controller -> controller.getClass()) - .forEach(classes::add); - + classes.addAll( + applicationManager + .getApplicationTypes() + .entrySet() + .stream() + .map(type -> type.getValue().applicationController()) + .collect(Collectors.toSet()) + ); + return classes; } diff --git a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/IsApplicationControllerFor.java b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/DefaultApplicationController.java similarity index 66% rename from ccm-core/src/main/java/org/libreccm/ui/admin/applications/IsApplicationControllerFor.java rename to ccm-core/src/main/java/org/libreccm/ui/admin/applications/DefaultApplicationController.java index a6921d67d..126ed7f15 100644 --- a/ccm-core/src/main/java/org/libreccm/ui/admin/applications/IsApplicationControllerFor.java +++ b/ccm-core/src/main/java/org/libreccm/ui/admin/applications/DefaultApplicationController.java @@ -18,31 +18,22 @@ */ package org.libreccm.ui.admin.applications; -import org.libreccm.web.CcmApplication; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import javax.inject.Qualifier; +import javax.enterprise.context.RequestScoped; +import javax.mvc.Controller; +import javax.ws.rs.Path; /** * * @author Jens Pelzetter */ -@Qualifier -@Retention(RetentionPolicy.RUNTIME) -@Target( - { - ElementType.METHOD, - ElementType.FIELD, - ElementType.PARAMETER, - ElementType.TYPE - } -) -public @interface IsApplicationControllerFor { +@RequestScoped +@Controller +@Path("/application") +public class DefaultApplicationController implements ApplicationController { + + @Override + public String getApplication() { + return ""; + } - String value(); - } diff --git a/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java b/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java index 9d663c2ee..a66cd3a61 100644 --- a/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java +++ b/ccm-core/src/main/java/org/libreccm/web/ApplicationType.java @@ -23,6 +23,9 @@ import com.arsdigita.ui.admin.applications.AbstractAppSettingsPane; import com.arsdigita.ui.admin.applications.DefaultApplicationInstanceForm; import com.arsdigita.ui.admin.applications.DefaultApplicationSettingsPane; +import org.libreccm.ui.admin.applications.ApplicationController; +import org.libreccm.ui.admin.applications.DefaultApplicationController; + import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; @@ -118,5 +121,7 @@ public @interface ApplicationType { Class instanceForm() default DefaultApplicationInstanceForm.class; Class settingsPane() default DefaultApplicationSettingsPane.class; + + Class applicationController() default DefaultApplicationController.class; } diff --git a/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/formGroupText.xhtml b/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/formGroupText.xhtml index ad68cfeca..1d9664069 100644 --- a/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/formGroupText.xhtml +++ b/ccm-core/src/main/resources/META-INF/resources/components/bootstrap/formGroupText.xhtml @@ -53,6 +53,7 @@
@@ -17,18 +16,20 @@

#{AdminMessages['applications.label']}

- +
  • - - #{type.title} - - - #{type.title} - + + + #{type.title} + + + #{type.title} + +

    @@ -36,7 +37,7 @@ #{AdminMessages['applications.types.singleton']} - #{AdminMessages.getMessage('applications.number_of_instances_one', [type.numberOfInstances])} + #{AdminMessages.getMessage('applications.number_of_instances_one', [type.numberOfInstances])} #{AdminMessages.getMessage('applications.number_of_instances', [type.numberOfInstances])} @@ -50,7 +51,7 @@
- +
diff --git a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml index 5d32e6eb2..afcdba4fb 100644 --- a/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml +++ b/ccm-core/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/categories/categorysystem-details.xhtml @@ -2,10 +2,10 @@ + xmlns:ui="http://xmlns.jcp.org/jsf/facelets"> diff --git a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/Shortcuts.java b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/Shortcuts.java index f9a838e64..2415c8f3d 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/Shortcuts.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/shortcuts/Shortcuts.java @@ -27,24 +27,29 @@ import org.libreccm.modules.RequiredModule; import org.libreccm.modules.ShutdownEvent; import org.libreccm.modules.UnInstallEvent; import org.libreccm.shortcuts.ui.ShortcutsSettingsPane; +import org.libreccm.ui.admin.applications.shortcuts.ShortcutsApplicationController; import org.libreccm.web.ApplicationType; /** - * The {@code Shortcuts} module for CCM. Defines the {@code Shortcuts} + * The {@code Shortcuts} module for CCM. Defines the {@code Shortcuts} * application and sets up the module when the module is installed. - * + * * @author Jens Pelzetter */ @Module( - requiredModules = { - @RequiredModule(module = CcmCore.class) - }, - applicationTypes = { - @ApplicationType(name = ShortcutsConstants.SHORTCUTS_APP_TYPE, - descBundle = ShortcutsConstants.SHORTCUTS_BUNDLE, - singleton = true, - settingsPane = ShortcutsSettingsPane.class, - creator = ShortcutsApplicationCreator.class)}) + requiredModules = { + @RequiredModule(module = CcmCore.class) + }, + applicationTypes = { + @ApplicationType( + name = ShortcutsConstants.SHORTCUTS_APP_TYPE, + descBundle = ShortcutsConstants.SHORTCUTS_BUNDLE, + singleton = true, + settingsPane = ShortcutsSettingsPane.class, + creator = ShortcutsApplicationCreator.class, + applicationController = ShortcutsApplicationController.class + )} +) public class Shortcuts implements CcmModule { @Override diff --git a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java index 101a60b0c..5824d0bc5 100644 --- a/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java +++ b/ccm-shortcuts/src/main/java/org/libreccm/ui/admin/applications/shortcuts/ShortcutsApplicationController.java @@ -18,17 +18,25 @@ */ package org.libreccm.ui.admin.applications.shortcuts; +import org.libreccm.core.CoreConstants; +import org.libreccm.security.AuthorizationRequired; +import org.libreccm.security.RequiresPrivilege; +import org.libreccm.shortcuts.Shortcut; import org.libreccm.shortcuts.ShortcutRepository; -import org.libreccm.shortcuts.ShortcutsConstants; import org.libreccm.ui.admin.applications.ApplicationController; -import org.libreccm.ui.admin.applications.IsApplicationControllerFor; + +import java.util.Optional; import javax.enterprise.context.RequestScoped; import javax.inject.Inject; import javax.mvc.Controller; import javax.mvc.Models; +import javax.transaction.Transactional; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; +import javax.ws.rs.POST; import javax.ws.rs.Path; +import javax.ws.rs.PathParam; /** * @@ -36,8 +44,7 @@ import javax.ws.rs.Path; */ @RequestScoped @Controller -//@IsApplicationControllerFor(ShortcutsConstants.SHORTCUTS_APP_TYPE) -@Path("/application") +@Path("/applications/shortcuts") public class ShortcutsApplicationController implements ApplicationController { @Inject @@ -48,11 +55,74 @@ public class ShortcutsApplicationController implements ApplicationController { @GET @Path("/") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) @Override public String getApplication() { models.put("shortcuts", shortcutRepository.findAll()); - + return "org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml"; } + @POST + @Path("/add") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String addShortcut( + @FormParam("urlKey") final String urlKey, + @FormParam("redirect") final String redirect + ) { + final Shortcut shortcut = new Shortcut(); + shortcut.setUrlKey(urlKey); + shortcut.setRedirect(redirect); + + shortcutRepository.save(shortcut); + + return "redirect:applications/shortcuts"; + } + + @POST + @Path("/{shortcutId}/edit") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String updateShortcut( + @PathParam("shortcutId") final long shortcutId, + @FormParam("urlKey") final String urlKey, + @FormParam("redirect") final String redirect + ) { + final Optional result = shortcutRepository + .findById(shortcutId); + + if (result.isPresent()) { + final Shortcut shortcut = result.get(); + shortcut.setUrlKey(urlKey); + shortcut.setRedirect(redirect); + + shortcutRepository.save(shortcut); + } + + return "redirect:applications/shortcuts"; + } + + @POST + @Path("/{shortcutId}/remove") + @AuthorizationRequired + @RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN) + @Transactional(Transactional.TxType.REQUIRED) + public String removeShortcut( + @PathParam("shortcutId") final long shortcutId + ) { + final Optional result = shortcutRepository + .findById(shortcutId); + + if (result.isPresent()) { + shortcutRepository.delete(result.get()); + } + + return "redirect:applications/shortcuts"; + } + } diff --git a/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml b/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml index 4b6e0f517..94496f2da 100644 --- a/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml +++ b/ccm-shortcuts/src/main/resources/WEB-INF/views/org/libreccm/ui/admin/applications/shortcuts/shortcuts.xhtml @@ -2,7 +2,9 @@ @@ -17,24 +19,48 @@ #{ShortcutAdminMessages['application_title']} - +

#{ShortcutAdminMessages['application_title']}

- -
- - - #{ShortcutAdminMessages['shortcuts.ui.admin.add_shortcut']} - + +
+ + +

#{ShortcutAdminMessages['shortcuts.ui.admin.add_shortcut.dialog.title']}

+
+ + + + + + + + +
- + @@ -43,18 +69,46 @@ diff --git a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties index 23af7122d..fa449df70 100644 --- a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties +++ b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources.properties @@ -33,3 +33,20 @@ shortcuts.ui.admin.redirect.error.invalid=The target of the redirect must be a a shortcuts.ui.admin.heading=Manage shortcuts shortcuts.ui.admin.table.empty=No shortcuts definied yet shortcuts.ui.admin.add_shortcut=Add shortcut +shortcuts.ui.admin.delete_dialog.cancel=Cancel +shortcuts.ui.admin.delete_dialog.confirm=Remove shortcut +shortcuts.ui.admin.delete_dialog.title=Confirm removal of shortcut +shortcuts.ui.admin.delete_dialog.message=Are you sure to remove the shortcut which redirects the URL {0} to {1}? +shortcuts.ui.admin.add_shortcut.dialog.title=Add shortcut +shortcuts.ui.admin.add_shortcut.dialog.urlkey.help=The short URL to redirect +shortcuts.ui.admin.add_shortcut.dialog.urlkey.label=Short URL +shortcuts.ui.admin.add_shortcut.dialog.redirect.help=The target URL to which the user is redirected +shortcuts.ui.admin.add_shortcut.dialog.redirect.label=Redirect target +shortcuts.ui.admin.add_shortcut.dialog.cancel=Cancel +shortcuts.ui.admin.add_shortcut.dialog.submit=Create shortcut +shortcuts.ui.admin.edit_shortcut.dialog.urlkey.help=The short URL +shortcuts.ui.admin.edit_shortcut.dialog.urlkey.label=Short URL +shortcuts.ui.admin.edit_shortcut.dialog.redirect.help=The target URL to which the user is redirected +shortcuts.ui.admin.edit_shortcut.dialog.redirect.label=Redirect target +shortcuts.ui.admin.edit_shortcut.dialog.cancel=Cancel +shortcuts.ui.admin.edit_shortcut.dialog.submit=Save diff --git a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties index 5d3b1aaae..d7348a459 100644 --- a/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties +++ b/ccm-shortcuts/src/main/resources/org/libreccm/shortcuts/ShortcutsResources_de.properties @@ -33,3 +33,20 @@ shortcuts.ui.admin.heading=Shortcuts verwalten shortcuts.ui.admin.table.empty=Es wurden noch keine Shortcuts angelegt. shortcuts.ui.admin.add_shortcut=Shortcut hinzuf\u00fcgen shortcuts.ui.admin.shortcuts_table.col_actions.header=Aktionen +shortcuts.ui.admin.delete_dialog.cancel=Abbbrechen +shortcuts.ui.admin.delete_dialog.confirm=Shortcut entfernen +shortcuts.ui.admin.delete_dialog.title=Confirm removal of shortcut +shortcuts.ui.admin.delete_dialog.message=Sind Sie sicher, dass Sie den Shortcut f\u00fcr die Umleitung von {0} nach {1} entfernen wollen? +shortcuts.ui.admin.add_shortcut.dialog.title=Shortcut hinzuf\u00fcgen +shortcuts.ui.admin.add_shortcut.dialog.urlkey.help=Die Kurz-URL, die umgeleitetet werden soll +shortcuts.ui.admin.add_shortcut.dialog.urlkey.label=Kurz-URL +shortcuts.ui.admin.add_shortcut.dialog.redirect.help=An diese URL wird weitergeleitet. +shortcuts.ui.admin.add_shortcut.dialog.redirect.label=Weiterleitungsziel +shortcuts.ui.admin.add_shortcut.dialog.cancel=Abbrechen +shortcuts.ui.admin.add_shortcut.dialog.submit=Shortcut anlegen +shortcuts.ui.admin.edit_shortcut.dialog.urlkey.help=Die Kurz-URL, die umgeleitetet werden soll +shortcuts.ui.admin.edit_shortcut.dialog.urlkey.label=Kurz-URL +shortcuts.ui.admin.edit_shortcut.dialog.redirect.help=An diese URL wird weitergeleitet. +shortcuts.ui.admin.edit_shortcut.dialog.redirect.label=Weiterleitungsziel +shortcuts.ui.admin.edit_shortcut.dialog.cancel=Abbrechen +shortcuts.ui.admin.edit_shortcut.dialog.submit=Speichern
#{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_url_key.header']} #{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_redirect.header']}#{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_actions.header']}#{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.col_actions.header']}
#{shortcut.urlKey} #{shortcut.redirect} - - - #{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.edit']} - + + +

#{ShortcutAdminMessages['shortcuts.ui.admin.edit_shortcut.dialog.title']}

+
+ + + + + + + + +
- - - #{ShortcutAdminMessages['shortcuts.ui.admin.shortcuts_table.delete']} - +