CCM NG: Several small bugfixes

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@5146 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2017-11-28 19:35:02 +00:00
parent e40256c375
commit 35dd01d8e2
23 changed files with 547 additions and 166 deletions

View File

@ -68,6 +68,9 @@
<Logger name="org.libreccm.modules.CcmIntegrator"
level="debug">
</Logger>
<Logger name="org.libreccm.pagemodel.PageModelManager"
level="debug">
</Logger>
<Logger name="org.libreccm.security.OneTimeAuthTokenCleaner"
level="debug">
</Logger>
@ -92,7 +95,7 @@
<Logger name="org.librecms.contentsection.rs.Images"
level="debug">
</Logger>
<Logger name="com.arsdigita.web.DefaultApplicationFileResolver"
<Logger name="com.arsdigita.web.DefaultApplicationFileResolver"
level="debug">
</Logger>
</Loggers>

View File

@ -18,11 +18,22 @@
*/
package com.arsdigita.cms.ui.category;
import com.arsdigita.bebop.*;
import com.arsdigita.bebop.event.*;
import com.arsdigita.bebop.ActionLink;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.List;
import com.arsdigita.bebop.Page;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SimpleContainer;
import com.arsdigita.bebop.SingleSelectionModel;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.parameters.ParameterModel;
import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.cms.CMS;
import com.arsdigita.cms.ui.BaseAdminPane;
import com.arsdigita.cms.ui.BaseDeleteForm;
import com.arsdigita.cms.ui.BaseTree;
@ -30,17 +41,18 @@ import com.arsdigita.cms.ui.VisibilityComponent;
import com.arsdigita.toolbox.ui.ActionGroup;
import com.arsdigita.toolbox.ui.Section;
import com.arsdigita.xml.Element;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.libreccm.categorization.Categorization;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.security.PermissionChecker;
import org.librecms.contentsection.privileges.AdminPrivileges;
import java.math.BigDecimal;
/**
* A split pane for the Category Administration UI.
@ -53,7 +65,7 @@ public final class CategoryAdminPane extends BaseAdminPane {
public static final String CONTEXT_SELECTED = "sel_context";
private static final String DEFAULT_USE_CONTEXT = "<default>";
private static final Logger LOGGER = LogManager.getLogger(
CategoryAdminPane.class);
CategoryAdminPane.class);
private final SingleSelectionModel m_contextModel;
private final Tree m_categoryTree;
private final SingleSelectionModel m_model;
@ -63,16 +75,18 @@ public final class CategoryAdminPane extends BaseAdminPane {
public CategoryAdminPane() {
super();
m_contextModel = new UseContextSelectionModel(new StringParameter(CONTEXT_SELECTED));
m_contextModel = new UseContextSelectionModel(new StringParameter(
CONTEXT_SELECTED));
/* Left column */
/* Use context section */
/* Use context section */
List list = new List(new CategoryUseContextModelBuilder());
list.setSelectionModel(m_contextModel);
list.addChangeListener(new ContextSelectionListener());
/* Category tree section */
m_categoryTree = new BaseTree(new CategoryTreeModelBuilder(m_contextModel));
m_categoryTree = new BaseTree(new CategoryTreeModelBuilder(
m_contextModel));
m_categoryTree.addChangeListener(new SelectionListener());
m_model = m_categoryTree.getSelectionModel();
@ -87,11 +101,12 @@ public final class CategoryAdminPane extends BaseAdminPane {
contextGroup.setSubject(list);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(PermissionChecker.class);
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
if (permissionChecker.isPermitted(AdminPrivileges.ADMINISTER_CATEGORIES)) {
ActionLink addContextAction = new ActionLink(new Label(gz(
"cms.ui.category.add_use_context")));
"cms.ui.category.add_use_context")));
Form addContextForm = new AddUseContextForm(m_contextModel);
getBody().add(addContextForm);
getBody().connect(addContextAction, addContextForm);
@ -119,8 +134,9 @@ public final class CategoryAdminPane extends BaseAdminPane {
setEdit(gz("cms.ui.category.edit"),
new CategoryEditForm(m_parent, m_category));
setDelete(new DeleteLink(new Label(gz("cms.ui.category.delete"))), new DeleteForm(
new SimpleContainer()));
setDelete(new DeleteLink(new Label(gz("cms.ui.category.delete"))),
new DeleteForm(
new SimpleContainer()));
setIntroPane(new Label(gz("cms.ui.category.intro")));
setItemPane(new CategoryItemPane(m_model,
@ -157,7 +173,6 @@ public final class CategoryAdminPane extends BaseAdminPane {
//String context = getUseContext(state);
//boolean isDefaultContext =
// (context == null) || DEFAULT_USE_CONTEXT.equals(context);
//if (cat.isRoot() || !cat.getChildren().isEmpty()) {
// m_alternativeLabel.generateXML(state, parent);
//} else {
@ -175,8 +190,7 @@ public final class CategoryAdminPane extends BaseAdminPane {
Label catLabel = new Label();
catLabel.addPrintListener(pe -> {
Label label = (Label) pe.getTarget();
Category cat =
m_category.getCategory(pe.getPageState());
Category cat = m_category.getCategory(pe.getPageState());
java.util.List<Category> descendants = cat.getSubCategories();
java.util.List<Categorization> catObjects = cat.getObjects();
@ -191,7 +205,8 @@ public final class CategoryAdminPane extends BaseAdminPane {
sb.append(" descendant object(s). ");
}
if (descendants.size() > 0 || catObjects.size() > 0) {
sb.append("Descendants will be orphaned, if this category is removed.");
sb.append(
"Descendants will be orphaned, if this category is removed.");
}
label.setLabel(gz(sb.toString()));
});
@ -200,11 +215,13 @@ public final class CategoryAdminPane extends BaseAdminPane {
@Override
public final void process(final FormSectionEvent e)
throws FormProcessException {
throws FormProcessException {
final PageState state = e.getPageState();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PermissionChecker permissionChecker = cdiUtil.findBean(PermissionChecker.class);
final CategoryRepository repository = cdiUtil.findBean(CategoryRepository.class);
final PermissionChecker permissionChecker = cdiUtil.findBean(
PermissionChecker.class);
final CategoryRepository repository = cdiUtil.findBean(
CategoryRepository.class);
final Category category = m_category.getCategory(state);
if (category == null) {
return;
@ -214,7 +231,8 @@ public final class CategoryAdminPane extends BaseAdminPane {
// category,
// Kernel.getContext().
// getParty()));
permissionChecker.checkPermission(AdminPrivileges.ADMINISTER_CATEGORIES, category);
permissionChecker.checkPermission(
AdminPrivileges.ADMINISTER_CATEGORIES, category);
// if (category.isRoot()) {
// Category root =
@ -226,8 +244,8 @@ public final class CategoryAdminPane extends BaseAdminPane {
// }
// m_contextModel.setSelectedKey(state, DEFAULT_USE_CONTEXT);
// } else {
Category parent = category.getParentCategory();
m_model.setSelectedKey(state, parent.getUniqueId());
Category parent = category.getParentCategory();
m_model.setSelectedKey(state, parent.getUniqueId());
// }
//category.deleteCategoryAndOrphan();
@ -242,7 +260,8 @@ public final class CategoryAdminPane extends BaseAdminPane {
protected final Object initialValue(final PageState state) {
final String id = m_model.getSelectedKey(state).toString();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository repository = cdiUtil.findBean(CategoryRepository.class);
final CategoryRepository repository = cdiUtil.findBean(
CategoryRepository.class);
if (id == null) {
return null;
} else {
@ -277,7 +296,6 @@ public final class CategoryAdminPane extends BaseAdminPane {
// }
//
// }
private class UseContextSelectionModel extends ParameterSingleSelectionModel {
public UseContextSelectionModel(ParameterModel m) {
@ -304,15 +322,26 @@ public final class CategoryAdminPane extends BaseAdminPane {
public class ContextSelectionListener implements ChangeListener {
public final void stateChanged(final ChangeEvent e) {
LOGGER.debug("Selection state changed; I may change " + "the body's visible pane");
public final void stateChanged(final ChangeEvent event) {
LOGGER.debug("Selection state changed; I may change "
+ "the body's visible pane");
final PageState state = e.getPageState();
final PageState state = event.getPageState();
getBody().reset(state);
if (m_contextModel.isSelected(state)) {
final Category root = (Category) m_contextModel.getSelectedKey(state);
final String rootCategoryId = (String) m_contextModel
.getSelectedKey(state);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil
.findBean(CategoryRepository.class);
final Category root = categoryRepo
.findById(Long.parseLong(rootCategoryId))
.orElseThrow(() -> new UnexpectedErrorException(String
.format("No Category with ID %s in the database.",
rootCategoryId)));
if (root != null) {
m_model.setSelectedKey(state, root.getUniqueId());
@ -321,11 +350,13 @@ public final class CategoryAdminPane extends BaseAdminPane {
}
if (m_model.isSelected(state)) {
LOGGER.debug("The selection model is selected; displaying " + "the item pane");
LOGGER.debug("The selection model is selected; displaying "
+ "the item pane");
getBody().push(state, getItemPane());
}
}
}
}

View File

@ -109,32 +109,29 @@ public class ItemListComponentForm
final PageState state,
final FormData data) {
final Object[] descendingValues = (Object[]) data.get(DESCENDING);
final Object[] descendingValues = (Object[]) data.get(DESCENDING_BOX);
final String limitToTypeValue = data.getString(LIMIT_TO_TYPE);
final String pageSizeValue = data.getString(PAGE_SIZE);
final String listOrderValue = data.getString(LIST_ORDER);
final boolean descendingValue;
if (descendingValues != null
&& descendingValues.length != 0
&& DESCENDING.equals(descendingValues[0])) {
descendingValue = true;
} else {
descendingValue = false;
}
final boolean descendingValue = isDescending(descendingValues);
final List<String> listOrder = Arrays
.stream(listOrderValue.split("\n"))
.collect(Collectors.toList());
componentModel.setDescending(descendingValue);
componentModel.setLimitToTypes(limitToTypeValue);
componentModel.setLimitToType(limitToTypeValue);
componentModel.setPageSize(Integer.parseInt(pageSizeValue));
componentModel.setListOrder(listOrder);
}
private boolean isDescending(final Object[] descendingValues) {
return descendingValues != null
&& descendingValues.length != 0
&& DESCENDING.equals(descendingValues[0]);
}
@Override
public void init(final FormSectionEvent event)
throws FormProcessException {
@ -145,21 +142,23 @@ public class ItemListComponentForm
final ItemListComponent component = getComponentModel();
final Object[] descendingValue;
if (component.isDescending()) {
descendingValue = new Object[]{DESCENDING};
} else {
descendingValue = new Object[]{};
if (component != null) {
final Object[] descendingValue;
if (component.isDescending()) {
descendingValue = new Object[]{DESCENDING};
} else {
descendingValue = new Object[]{};
}
descendingBox.setValue(state, descendingValue);
limitToTypeField.setValue(state, component.getLimitToType());
pageSizeField.setValue(state, Integer.toString(component
.getPageSize()));
listOrderArea.setValue(state,
String.join("\n", component.getListOrder()));
}
descendingBox.setValue(state, descendingValue);
limitToTypeField.setValue(state, component.getLimitToType());
pageSizeField.setValue(state, Integer.toString(component.getPageSize()));
listOrderArea.setValue(state,
String.join("\n", component.getListOrder()));
}
@Override
@ -186,4 +185,5 @@ public class ItemListComponentForm
}
}
}
}

View File

@ -21,7 +21,6 @@ package com.arsdigita.cms.ui.pages;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.FormModel;
import com.arsdigita.bebop.FormProcessException;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.Page;
@ -33,7 +32,6 @@ import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.ChangeEvent;
import com.arsdigita.bebop.event.ChangeListener;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.form.Option;
@ -241,7 +239,7 @@ public class PagesAdminPage extends Page {
final PageModelRepository pageModelRepo = cdiUtil
.findBean(PageModelRepository.class);
final List<PageModel> pageModels = pageModelRepo
.findByApplication(pagesInstance);
.findDraftByApplication(pagesInstance);
final GlobalizationHelper globalizationHelper = cdiUtil
.findBean(GlobalizationHelper.class);

View File

@ -87,6 +87,7 @@ import java.util.Properties;
instanceForm = ApplicationInstanceForm.class,
settingsPane = SettingsPane.class,
descBundle = CmsConstants.CMS_BUNDLE,
titleKey = "pages_application.title",
creator = PagesCreator.class,
servletPath = "/templates/servlet/pages"
)

View File

@ -79,6 +79,10 @@ public class ItemListComponent extends ComponentModel {
@Column(name = "LIST_ORDER")
private List<String> listOrder;
public ItemListComponent() {
listOrder = new ArrayList<>();
}
public boolean isDescending() {
return descending;
}
@ -91,7 +95,7 @@ public class ItemListComponent extends ComponentModel {
return limitToType;
}
public void setLimitToTypes(final String limitToType) {
public void setLimitToType(final String limitToType) {
this.limitToType = limitToType;
}

View File

@ -495,3 +495,4 @@ cms.ui.pages.title=Administer pages
cms.ui.pages.page_config_for_category=Page Configuration for category {0}
cms.ui.pages.assigned_page_model.inherit=Inherit from parent
cms.ui.pages.no_category_selected=No category selected
pages_application.title=Pages

View File

@ -492,3 +492,4 @@ cms.ui.pages.title=Seitenbaum verwalten
cms.ui.pages.page_config_for_category=Seiten-Konfiguration f\u00fcr Kategorie {0}
cms.ui.pages.assigned_page_model.inherit=PageModel der \u00fcbergeordneten Seite verwenden
cms.ui.pages.no_category_selected=Keine Kategorie ausgew\u00e4hlt
pages_application.title=Pages

View File

@ -451,3 +451,4 @@ cms.ui.pages.title=Administer pages
cms.ui.pages.page_config_for_category=Page Configuration for category {0}
cms.ui.pages.assigned_page_model.inherit=Inherit from parent
cms.ui.pages.no_category_selected=No category selected
pages_application.title=Pages

View File

@ -26,7 +26,7 @@ import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.PropertySheet;
import com.arsdigita.bebop.event.FormProcessListener;
import com.arsdigita.bebop.event.ActionEvent;
import com.arsdigita.bebop.event.FormSectionEvent;
import com.arsdigita.bebop.event.PrintEvent;
import com.arsdigita.bebop.event.PrintListener;
@ -42,6 +42,7 @@ import org.libreccm.pagemodel.ComponentModel;
import org.libreccm.pagemodel.ComponentModels;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelComponentModel;
import org.libreccm.pagemodel.PageModelManager;
import org.libreccm.pagemodel.PageModelRepository;
import java.util.List;
@ -55,6 +56,10 @@ import java.util.TooManyListenersException;
*/
class PageModelDetails extends BoxPanel {
private final PageModelsTab pageModelTab;
private final ParameterSingleSelectionModel<String> selectedModelId;
private final ParameterSingleSelectionModel<String> selectedComponentId;
public PageModelDetails(
final PageModelsTab pageModelTab,
final ParameterSingleSelectionModel<String> selectedModelId,
@ -62,6 +67,10 @@ class PageModelDetails extends BoxPanel {
super(BoxPanel.VERTICAL);
this.pageModelTab = pageModelTab;
this.selectedModelId = selectedModelId;
this.selectedComponentId = selectedComponentId;
final ActionLink backLink = new ActionLink(new GlobalizedMessage(
"ui.admin.pagemodels.details.back",
AdminUiConstants.ADMIN_BUNDLE));
@ -74,20 +83,7 @@ class PageModelDetails extends BoxPanel {
final Label heading = new Label();
heading.setClassAttr("heading");
heading.addPrintListener(event -> {
final PageState state = event.getPageState();
final Label target = (Label) event.getTarget();
final PageModelRepository pageModelRepo = CdiUtil
.createCdiUtil()
.findBean(PageModelRepository.class);
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelId.getSelectedKey(state)))
.get();
target.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.details.heading",
AdminUiConstants.ADMIN_BUNDLE,
new String[]{pageModel.getName()}));
});
heading.addPrintListener(this::printHeading);
super.add(heading);
final PropertySheet propertySheet = new PropertySheet(
@ -100,7 +96,16 @@ class PageModelDetails extends BoxPanel {
editProperties.addActionListener(event -> {
pageModelTab.showPageModelForm(event.getPageState());
});
super.add(editProperties);
final ActionLink publishLink = new ActionLink(new GlobalizedMessage(
"ui.admin.pagemodels.details.publish",
AdminUiConstants.ADMIN_BUNDLE));
publishLink.addActionListener(this::publishPageModel);
final BoxPanel actionsPanel = new BoxPanel(BoxPanel.HORIZONTAL);
actionsPanel.add(editProperties);
actionsPanel.add(publishLink);
super.add(actionsPanel);
final AddComponentForm addComponentForm = new AddComponentForm(
pageModelTab);
@ -112,13 +117,49 @@ class PageModelDetails extends BoxPanel {
super.add(componentsTable);
}
private void printHeading(final PrintEvent event) {
final PageState state = event.getPageState();
final Label target = (Label) event.getTarget();
final PageModelRepository pageModelRepo = CdiUtil
.createCdiUtil()
.findBean(PageModelRepository.class);
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedModelId.getSelectedKey(state)))
.get();
target.setLabel(new GlobalizedMessage(
"ui.admin.pagemodels.details.heading",
AdminUiConstants.ADMIN_BUNDLE,
new String[]{pageModel.getName()}));
}
private void publishPageModel(final ActionEvent event) {
final PageState state = event.getPageState();
final String selectedPageModelIdStr = selectedModelId
.getSelectedKey(state);
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final PageModelManager pageModelManager = cdiUtil
.findBean(PageModelManager.class);
final PageModelRepository pageModelRepo = cdiUtil
.findBean(PageModelRepository.class);
final PageModel pageModel = pageModelRepo
.findById(Long.parseLong(selectedPageModelIdStr))
.orElseThrow(() -> new UnexpectedErrorException(String
.format("No PageModel with ID %s in the database.",
selectedPageModelIdStr)));
final PageModel draftModel = pageModelManager.getDraftVersion(pageModel);
pageModelManager.publish(draftModel);
}
/**
* Form for selecting the type of {@link ComponentModel} to add to the
* {@link PageModel}.
*/
private class AddComponentForm
extends Form
implements FormProcessListener {
private class AddComponentForm extends Form {
private final PageModelsTab pageModelTab;
private final SingleSelect selectType;
@ -152,10 +193,9 @@ class PageModelDetails extends BoxPanel {
AdminUiConstants.ADMIN_BUNDLE));
super.add(submit);
super.addProcessListener(this);
super.addProcessListener(this::process);
}
@Override
public void process(final FormSectionEvent event)
throws FormProcessException {

View File

@ -82,7 +82,7 @@ class PageModelsController implements Serializable {
protected List<PageModelsTableRow> findPageModels() {
return pageModelRepo
.findAll()
.findAllDraftModels()
.stream()
.map(this::buildRow)
.sorted()
@ -109,7 +109,7 @@ class PageModelsController implements Serializable {
applicationId)));
return !pageModelRepo
.findByApplicationAndName(application, name)
.findLiveByApplicationAndName(application, name)
.isPresent();
}

View File

@ -23,6 +23,7 @@ import com.vaadin.data.provider.AbstractBackEndHierarchicalDataProvider;
import com.vaadin.data.provider.HierarchicalQuery;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.l10n.LocalizedTextsUtil;
import org.libreccm.web.ApplicationManager;
import org.libreccm.web.ApplicationRepository;
import org.libreccm.web.ApplicationType;
@ -99,10 +100,10 @@ class ApplicationTreeDataProvider
private ApplicationTreeNode buildApplicationTreeNode(
final ApplicationType type) {
final ResourceBundle bundle = ResourceBundle
.getBundle(type.descBundle());
final LocalizedTextsUtil textsUtil = globalizationHelper
.getLocalizedTextsUtil(type.descBundle());
final String title = bundle.getString(type.titleKey());
final String title = textsUtil.getText(type.titleKey());
final ApplicationTreeNode node = new ApplicationTreeNode();
node.setTitle(title);
@ -155,8 +156,18 @@ class ApplicationTreeDataProvider
node.setNodeId(application.getUuid());
node.setNodeType(ApplicationTreeNodeType.APPLICATION_NODE);
node.setTitle(globalizationHelper
.getValueFromLocalizedString(application.getTitle()));
final String title;
if (globalizationHelper
.getValueFromLocalizedString(application.getTitle()) == null
|| globalizationHelper
.getValueFromLocalizedString(application.getTitle()).isEmpty()) {
title = application.getPrimaryUrl();
} else {
title =globalizationHelper
.getValueFromLocalizedString(application.getTitle());
}
node.setTitle(title);
return node;
}

View File

@ -26,6 +26,7 @@ import com.vaadin.ui.Component;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Grid;
import com.vaadin.ui.HorizontalSplitPanel;
import com.vaadin.ui.Label;
import com.vaadin.ui.Tree;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
@ -33,9 +34,6 @@ import com.vaadin.ui.themes.ValoTheme;
import org.libreccm.l10n.LocalizedTextsUtil;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.ui.ConfirmDialog;
import org.libreccm.web.CcmApplication;
import java.util.concurrent.Callable;
/**
*
@ -59,8 +57,8 @@ class PageModelsTab extends CustomComponent {
final Tree<ApplicationTreeNode> applicationTree = new Tree<>(
adminViewController.getApplicationTreeDataProvider());
applicationTree.addItemClickListener(event -> {
});
applicationTree.setItemCaptionGenerator(ApplicationTreeNode::getTitle);
applicationTree.setItemCollapseAllowedProvider(node -> {
return !node.getNodeType().equals(ApplicationTreeNodeType.ROOT_NODE);
});
@ -102,9 +100,27 @@ class PageModelsTab extends CustomComponent {
adminViewController))
.setId(COL_DELETE);
super.setCompositionRoot(new HorizontalSplitPanel(applicationTree,
pageModelsGrid));
pageModelsGrid.setVisible(false);
final Label placeholder = new Label(localizedTextsUtil.getText(
"ui.admin.pagemodels.select_application"));
final VerticalLayout layout = new VerticalLayout(pageModelsGrid,
placeholder);
applicationTree.addItemClickListener(event -> {
final PageModelsTableDataProvider dataProvider
= (PageModelsTableDataProvider) pageModelsGrid
.getDataProvider();
dataProvider.setApplicationUuid(event.getItem().getNodeId());
pageModelsGrid.setVisible(true);
placeholder.setVisible(false);
});
final HorizontalSplitPanel panel = new HorizontalSplitPanel(
applicationTree, layout);
panel.setSplitPosition(33.0f);
super.setCompositionRoot(panel);
}
private Component buildEditButton(final PageModelsTableRow row,

View File

@ -21,10 +21,12 @@ package org.libreccm.admin.ui;
import com.vaadin.cdi.ViewScoped;
import com.vaadin.data.provider.AbstractBackEndDataProvider;
import com.vaadin.data.provider.Query;
import org.libreccm.core.UnexpectedErrorException;
import org.libreccm.l10n.GlobalizationHelper;
import org.libreccm.pagemodel.PageModel;
import org.libreccm.pagemodel.PageModelManager;
import org.libreccm.pagemodel.PageModelVersion;
import org.libreccm.web.ApplicationRepository;
import org.libreccm.web.CcmApplication;
import java.util.stream.Stream;
@ -46,6 +48,9 @@ class PageModelsTableDataProvider
private static final long serialVersionUID = 8052894182508842905L;
@Inject
private ApplicationRepository applicationRepo;
@Inject
private EntityManager entityManager;
@ -66,6 +71,16 @@ class PageModelsTableDataProvider
refreshAll();
}
@Transactional(Transactional.TxType.REQUIRED)
public void setApplicationUuid(final String uuid) {
application = applicationRepo
.findByUuid(uuid)
.orElseThrow(() -> new UnexpectedErrorException(String
.format("No Application with UUID %s in the database.",
uuid)));
refreshAll();
}
@Transactional(Transactional.TxType.REQUIRED)
@Override
protected Stream<PageModelsTableRow> fetchFromBackEnd(
@ -86,8 +101,8 @@ class PageModelsTableDataProvider
.and(builder.equal(from.get("application"), application),
builder.equal(from.get("version"),
PageModelVersion.DRAFT)))
.orderBy(builder.asc(from.get("name")))
.orderBy(builder.asc(from.get("title")));
.orderBy(builder.asc(from.get("name")));
// .orderBy(builder.asc(from.get("title")));
return entityManager
.createQuery(criteriaQuery)

View File

@ -50,8 +50,9 @@ import javax.persistence.OneToMany;
import javax.persistence.Table;
/**
* A {@link PageModel} is used by a {@link PageRenderer} implementation to render
* a page. The {@code PageModel} specifics which components are used on a page.
* A {@link PageModel} is used by a {@link PageRenderer} implementation to
* render a page. The {@code PageModel} specifics which components are used on a
* page.
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*
@ -63,6 +64,16 @@ import javax.persistence.Table;
@Inheritance(strategy = InheritanceType.JOINED)
@Table(name = "PAGE_MODELS", schema = CoreConstants.DB_SCHEMA)
@NamedQueries({
@NamedQuery(
name = "PageModel.findAllDraftModels",
query = "SELECT p FROM PageModel p "
+ "WHERE p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT")
,
@NamedQuery(
name = "PageModel.findAllLiveModels",
query = "SELECT p FROM PageModel p "
+ "WHERE p.version = org.libreccm.pagemodel.PageModelVersion.LIVE")
,
@NamedQuery(
name = "PageModel.findDraftVersion",
query = "SELECT p FROM PageModel p "
@ -84,19 +95,47 @@ import javax.persistence.Table;
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE")
,
@NamedQuery(
name = "PageModel.findByApplication",
name = "PageModel.findDraftByApplication",
query = "SELECT p FROM PageModel p "
+ "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT"
)
,
@NamedQuery(
name = "PageModel.findDraftByApplicationAndName",
query = "SELECT p FROM PageModel p "
+ "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT"
)
,
@NamedQuery(
name = "PageModel.countDraftByApplicationAndName",
query = "SELECT COUNT(p) FROM PageModel p "
+ "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT"
)
,
@NamedQuery(
name = "PageModel.countDraftByApplication",
query = "SELECT COUNT(p) FROM PageModel p "
+ "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.DRAFT"
)
,
@NamedQuery(
name = "PageModel.findLiveByApplication",
query = "SELECT p FROM PageModel p "
+ "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE")
,
@NamedQuery(
name = "PageModel.countByApplication",
name = "PageModel.countLiveByApplication",
query = "SELECT COUNT(p) FROM PageModel p "
+ "WHERE p.application = :application "
+ "AND p.version = org.libreccm.pagemodel.PageModelVersion.LIVE")
,
@NamedQuery(
name = "PageModel.findByApplicationAndName",
name = "PageModel.findLiveByApplicationAndName",
query = "SELECT p FROM PageModel p "
+ "WHERE p.name = :name "
+ "AND p.application = :application "
@ -104,7 +143,7 @@ import javax.persistence.Table;
)
,
@NamedQuery(
name = "PageModel.countByApplicationAndName",
name = "PageModel.countLiveByApplicationAndName",
query = "SELECT COUNT(p) FROM PageModel p "
+ "WHERE p.name = :name "
+ "AND p.application = :application "
@ -206,6 +245,7 @@ public class PageModel implements Serializable {
public PageModel() {
title = new LocalizedString();
description = new LocalizedString();
components = new ArrayList<>();
}
public long getPageModelId() {

View File

@ -46,6 +46,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.ServiceLoader;
import java.util.Set;
@ -114,7 +115,7 @@ public class PageModelManager {
/**
* Creates a new {@link PageModel} for the provided application. The method
* tries to retrieve the appropriate application by using
* {@link PageModelRepository#findByApplicationAndName(org.libreccm.web.CcmApplication, java.lang.String)}.
* {@link PageModelRepository#findLiveByApplicationAndName(org.libreccm.web.CcmApplication, java.lang.String)}.
* Please note that this method will always return the
* <strong>draft</strong>
* version of the page model.
@ -134,23 +135,24 @@ public class PageModelManager {
final CcmApplication application,
final String type) {
if (application == null) {
Objects.requireNonNull(application,
"Can't create a page model for application null");
Objects.requireNonNull(name, "Then name of a Pagemodel can't be null.");
if (name.isEmpty()
|| name.matches("\\s*")) {
throw new IllegalArgumentException(
"Can't create a page model for application null");
"The name of a PageModel can't be empty.");
}
if (name == null || name.trim().isEmpty()) {
throw new IllegalArgumentException(
"The name of a page model can't be null or empty.");
}
LOGGER.debug(
"Creating new PageModel with name \"{}\" for application \"{}\" and type \"{}\".",
name,
application.getPrimaryUrl(),
type);
final long count = pageModelRepo.countByApplicationAndName(application,
name);
final long count = pageModelRepo.countLiveByApplicationAndName(
application,
name);
if (count > 0) {
LOGGER.error("A page model with the name \"{}\" for the "
@ -257,6 +259,11 @@ public class PageModelManager {
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
public PageModel publish(final PageModel pageModel) {
Objects.requireNonNull(pageModel, "Can't publish PageModel null.");
LOGGER.debug("Publishing PageModel \"{}\"...", pageModel.getName());
final PageModel draftModel = getDraftVersion(pageModel);
final PageModel liveModel;
@ -266,6 +273,7 @@ public class PageModelManager {
liveModel = new PageModel();
}
liveModel.setName(draftModel.getName());
liveModel.setVersion(PageModelVersion.LIVE);
liveModel.setModelUuid(draftModel.getModelUuid());
@ -274,7 +282,7 @@ public class PageModelManager {
liveModel.getTitle().addValue(entry.getKey(), entry.getValue());
}
for (Map.Entry<Locale, String> entry : liveModel.getDescription()
for (Map.Entry<Locale, String> entry : draftModel.getDescription()
.getValues().entrySet()) {
liveModel.getDescription().addValue(entry.getKey(),
entry.getValue());
@ -283,12 +291,16 @@ public class PageModelManager {
liveModel.setApplication(draftModel.getApplication());
liveModel.setType(draftModel.getType());
LOGGER.debug("Publishing ComponentModels of PageModel \"{}\"...",
draftModel.getName());
liveModel.clearComponents();
for (final ComponentModel draft : draftModel.getComponents()) {
final ComponentModel live = publishComponentModel(draft);
addComponentModel(liveModel, live);
}
LOGGER.debug("Successfully published PageModel \"{}\".",
liveModel.getName());
return liveModel;
}
@ -304,6 +316,11 @@ public class PageModelManager {
@SuppressWarnings("unchecked")
private ComponentModel publishComponentModel(final ComponentModel draftModel) {
Objects.requireNonNull(draftModel, "Can't publish ComponentModel null.");
LOGGER.debug("Publishing ComponentModel \"{}\"...",
draftModel.getKey());
final Class<? extends ComponentModel> clazz = draftModel.getClass();
final ComponentModel liveModel;
@ -324,6 +341,12 @@ public class PageModelManager {
for (final PropertyDescriptor propertyDescriptor : beanInfo.
getPropertyDescriptors()) {
LOGGER.debug(
"Publishing property \"{}\" of ComponentModel \"{}\"...",
propertyDescriptor.getName(),
draftModel.getKey());
final Class<?> propType = propertyDescriptor.getPropertyType();
final Method readMethod = propertyDescriptor.getReadMethod();
final Method writeMethod = propertyDescriptor.getWriteMethod();
@ -339,18 +362,18 @@ public class PageModelManager {
if (propType != null
&& propType.isAssignableFrom(List.class)) {
final List<Object> source;
final List<Object> target;
try {
source = (List<Object>) readMethod.invoke(draftModel);
target = (List<Object>) readMethod.invoke(liveModel);
final List<Object> source = (List<Object>) readMethod
.invoke(draftModel);
final List<Object> target = new ArrayList<>();
target.addAll(source);
writeMethod.invoke(draftModel, target);
} catch (IllegalAccessException
| IllegalArgumentException
| InvocationTargetException ex) {
throw new UnexpectedErrorException(ex);
}
target.addAll(source);
} else if (propType != null
&& propType.isAssignableFrom(Map.class)) {
@ -399,6 +422,8 @@ public class PageModelManager {
componentModelRepo.save(liveModel);
LOGGER.debug("Successfully published ComponentModel \"{}\".",
liveModel.getKey());
return liveModel;
}
@ -413,6 +438,7 @@ public class PageModelManager {
*/
private boolean propertyIsExcluded(final String name) {
final String[] excluded = new String[]{
"class",
"uuid",
"modelUuid"
};

View File

@ -27,7 +27,9 @@ import org.libreccm.web.CcmApplication;
import javax.enterprise.context.RequestScoped;
import javax.persistence.TypedQuery;
import javax.transaction.Transactional;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.UUID;
@ -39,6 +41,8 @@ import java.util.UUID;
@RequestScoped
public class PageModelRepository extends AbstractEntityRepository<Long, PageModel> {
private static final long serialVersionUID = -7240418542790568571L;
@Override
public Class<PageModel> getEntityClass() {
return PageModel.class;
@ -46,9 +50,8 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
@Override
public boolean isNew(final PageModel pageModel) {
if (pageModel == null) {
throw new IllegalArgumentException("PageModel can't be null.");
}
Objects.requireNonNull(pageModel);
return pageModel.getPageModelId() == 0;
}
@ -60,9 +63,8 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
*/
@Override
public void initNewEntity(final PageModel pageModel) {
if (pageModel == null) {
throw new IllegalArgumentException("PageModel can't be null.");
}
Objects.requireNonNull(pageModel);
final String uuid = UUID.randomUUID().toString();
@ -82,24 +84,57 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
}
/**
* Finds the draft version of all {@link PageModel}s for the provided
* Find all draft versions of {@link PageModel}s.
*
* @return A list with all draft versions of {@link PageModel}s.
*/
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
@Transactional(Transactional.TxType.REQUIRED)
public List<PageModel> findAllDraftModels() {
final TypedQuery<PageModel> query = getEntityManager()
.createNamedQuery("PageModel.findAllDraftModels", PageModel.class);
return query.getResultList();
}
/**
* Find all live versions of {@link PageModel}s.
*
* @return A list with all draft versions of {@link PageModel}s.
*/
@Transactional(Transactional.TxType.REQUIRED)
public List<PageModel> findAllLiveModels() {
final TypedQuery<PageModel> query = getEntityManager()
.createNamedQuery("PageModel.findAllLiveModels", PageModel.class);
return query.getResultList();
}
/**
* Finds the draft versions of all {@link PageModel}s for the provided
* application.
*
* @param application The application for which the {@link PageModel}s are
* retrieved.
*
* @return A list of the {@link PageModel}s defined for the provided {
*
* @coded application}.
* @return A list of the {@link PageModel}s defined for the provided
* {@code application}.
*/
public List<PageModel> findByApplication(final CcmApplication application) {
if (application == null) {
throw new IllegalArgumentException(
"Can't find page models for application null");
}
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public List<PageModel> findDraftByApplication(
final CcmApplication application) {
final TypedQuery<PageModel> query = getEntityManager().createNamedQuery(
"PageModel.findByApplication", PageModel.class);
Objects.requireNonNull(application,
"Can't find page models for application null");
final TypedQuery<PageModel> query = getEntityManager()
.createNamedQuery("PageModel.findDraftByApplication",
PageModel.class);
query.setParameter("application", application);
return query.getResultList();
@ -108,20 +143,22 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
/**
* Counts the {@link PageModel}s (draft version) defined for a application.
*
* @param application The application for which the {@link PageLink}s are
* @param application The application for which the {@link PageModels}s are
* counted.
*
* @return The number of {@link PageModel}s defined for the provided
* {@code application}.
*/
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public long countByApplication(final CcmApplication application) {
if (application == null) {
throw new IllegalArgumentException(
"Can't count page models for application null");
}
Objects.requireNonNull(application,
"Can't count page models for application null");
final TypedQuery<Long> query = getEntityManager().createNamedQuery(
"PageModel.countByApplication", Long.class);
"PageModel.countDraftByApplication", Long.class);
query.setParameter("application", application);
return query.getSingleResult();
@ -140,27 +177,27 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
* there is no {@link PageModel} matching the criteria an empty
* {@link Optional} is returned.
*/
public Optional<PageModel> findByApplicationAndName(
public Optional<PageModel> findDraftByApplicationAndName(
final CcmApplication application,
final String name) {
if (application == null) {
throw new IllegalArgumentException(
"Can't find page models for application null");
}
Objects.requireNonNull(application,
"Can't find page models for application null");
Objects.requireNonNull(name,
"The name of a page model can't be null or empty.");
if (name == null || name.trim().isEmpty()) {
if (name.isEmpty() || name.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of a page model can't be null or empty.");
}
final long count = countByApplicationAndName(application, name);
final long count = countLiveByApplicationAndName(application, name);
if (count == 0) {
return Optional.empty();
}
final TypedQuery<PageModel> query = getEntityManager().createNamedQuery(
"PageModel.findByApplicationAndName", PageModel.class);
"PageModel.findDraftByApplicationAndName", PageModel.class);
query.setParameter("application", application);
query.setParameter("name", name);
@ -178,21 +215,145 @@ public class PageModelRepository extends AbstractEntityRepository<Long, PageMode
* @return The number of {@link PageModel}s matching the criteria. Should be
* 0 or 1.
*/
public long countByApplicationAndName(final CcmApplication application,
final String name) {
@Transactional(Transactional.TxType.REQUIRED)
@AuthorizationRequired
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
public long countDraftByApplicationAndName(final CcmApplication application,
final String name) {
if (application == null) {
throw new IllegalArgumentException(
"Can't count page models for application null");
}
Objects.requireNonNull(application,
"Can't find page models for application null");
Objects.requireNonNull(name,
"The name of a page model can't be null or empty.");
if (name == null || name.trim().isEmpty()) {
if (name.isEmpty() || name.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of a page model can't be null or empty.");
}
final TypedQuery<Long> query = getEntityManager().createNamedQuery(
"PageModel.countByApplicationAndName", Long.class);
"PageModel.countDraftByApplicationAndName", Long.class);
query.setParameter("application", application);
query.setParameter("name", name);
return query.getSingleResult();
}
/**
* Finds the live versions of all {@link PageModel}s for the provided
* application.
*
* @param application The application for which the {@link PageModel}s are
* retrieved.
*
* @return A list of the {@link PageModel}s defined for the provided
* {@code application}.
*/
@Transactional(Transactional.TxType.REQUIRED)
public List<PageModel> findLiveByApplication(
final CcmApplication application) {
Objects.requireNonNull(application,
"Can't find page models for application null");
final TypedQuery<PageModel> query = getEntityManager()
.createNamedQuery("PageModel.findLiveByApplication",
PageModel.class);
query.setParameter("application", application);
return query.getResultList();
}
/**
* Counts the {@link PageModel}s (live version) defined for a application.
*
* @param application The application for which the {@link PageModels}s are
* counted.
*
* @return The number of {@link PageModel}s defined for the provided
* {@code application}.
*/
@Transactional(Transactional.TxType.REQUIRED)
public long countLiveByApplication(final CcmApplication application) {
Objects.requireNonNull(application,
"Can't count page models for application null");
final TypedQuery<Long> query = getEntityManager().createNamedQuery(
"PageModel.countLiveByApplication", Long.class);
query.setParameter("application", application);
return query.getSingleResult();
}
/**
* Finds a {@link PageModel} (live version) by the application and its
* {@code name}.
*
* @param application The application for which the {@link PageModel} is
* defined.
* @param name The name of the {@link PageModel}.
*
* @return An {@link Optional} containing the {@link PageModel} for the
* provided {@code application} with the provided {@code name}. If
* there is no {@link PageModel} matching the criteria an empty
* {@link Optional} is returned.
*/
@Transactional(Transactional.TxType.REQUIRED)
public Optional<PageModel> findLiveByApplicationAndName(
final CcmApplication application,
final String name) {
Objects.requireNonNull(application,
"Can't find page models for application null");
Objects.requireNonNull(name,
"The name of a page model can't be null or empty.");
if (name.isEmpty() || name.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of a page model can't be null or empty.");
}
final long count = countLiveByApplicationAndName(application, name);
if (count == 0) {
return Optional.empty();
}
final TypedQuery<PageModel> query = getEntityManager().createNamedQuery(
"PageModel.findLiveByApplicationAndName", PageModel.class);
query.setParameter("application", application);
query.setParameter("name", name);
return Optional.of(query.getSingleResult());
}
/**
* Counts the number of {@link PageModel} (live version) defined for the
* provided application with the provided name.
*
* @param application The application for which the {@link PageModel} is
* defined.
* @param name The name of the {@link PageModel}.
*
* @return The number of {@link PageModel}s matching the criteria. Should be
* 0 or 1.
*/
@Transactional(Transactional.TxType.REQUIRED)
public long countLiveByApplicationAndName(final CcmApplication application,
final String name) {
Objects.requireNonNull(application,
"Can't find page models for application null");
Objects.requireNonNull(name,
"The name of a page model can't be null or empty.");
if (name.isEmpty() || name.matches("\\s*")) {
throw new IllegalArgumentException(
"The name of a page model can't be null or empty.");
}
final TypedQuery<Long> query = getEntityManager().createNamedQuery(
"PageModel.countLiveByApplicationAndName", Long.class);
query.setParameter("application", application);
query.setParameter("name", name);

View File

@ -48,7 +48,7 @@ class PageTreeModel implements TreeModel {
PageModelRepository.class);
final CcmApplication application = ((ApplicationTreeNode) node)
.getApplication();
final long count = pageModelRepo.countByApplication(application);
final long count = pageModelRepo.countLiveByApplication(application);
return count > 0;
} else if (node instanceof PageModelTreeNode) {

View File

@ -54,7 +54,7 @@ import javax.persistence.Table;
name = "Site.findDefaultSite",
query = "SELECT s FROM Site s "
+ "WHERE s.defaultSite = true "
+ "ORDER BY s.domain"
+ "ORDER BY s.domainOfSite"
)
,
@NamedQuery(

View File

@ -671,7 +671,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name
ui.admin.pagemodels.table.columns.headers.title=Title
ui.admin.pagemodels.table.columns.headers.desc=Description
ui.admin.pagemodels.table.columns.headers.remove=Delete
\ \tui.admin.pagemodels.table.columns.remove.label=Delete
\ ui.admin.pagemodels.table.columns.remove.label=Delete
ui.admin.pagemodels.details.model_name=Name
ui.admin.pagemodels.details.model_title=Titel
ui.admin.pagemodels.details.model_application=Application
@ -680,3 +680,11 @@ ui.admin.pagemodels.details.edit_properties=Edit properties
ui.admin.pagemodels.components.key.label=ID
ui.admin.pagemodels.components.key.error.not_empty=The ID of a component can't be empty.
ui.admin.pagemodels.table.columns.remove.label=Delete
ui.admin.pagemodels.details.publish=(Re-)Publish
ui.admin.users.table.filter.groupname.placeholder=Name of Group
ui.admin.users.table.filter.groupname.description=Filter groups by name
ui.admin.roles.table.description=Roles
ui.admin.users.table.filter.rolename.placeholder=Name of role
ui.admin.users.table.filter.rolename.description=Filter roles by name
ui.admin.pagemodels.table.columns.headers.islive=Is live?
ui.admin.pagemodels.select_application=Please select an application

View File

@ -675,7 +675,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name
ui.admin.pagemodels.table.columns.headers.title=Titel
ui.admin.pagemodels.table.columns.headers.desc=Description
ui.admin.pagemodels.table.columns.headers.remove=L\u00f6schen
\ \tui.admin.pagemodels.table.columns.remove.label=L\u00f6schen
\ ui.admin.pagemodels.table.columns.remove.label=L\u00f6schen
ui.admin.pagemodels.details.model_name=Name
ui.admin.pagemodels.details.model_title=Titel
ui.admin.pagemodels.details.model_application=Applikation
@ -684,3 +684,11 @@ ui.admin.pagemodels.details.edit_properties=Bearbeiten
ui.admin.pagemodels.components.key.label=ID
ui.admin.pagemodels.components.key.error.not_empty=Die ID einer Komponente darf nicht leer sein.
ui.admin.pagemodels.table.columns.remove.label=L\u00f6schen
ui.admin.pagemodels.details.publish=(Re-)Publizieren
ui.admin.users.table.filter.groupname.placeholder=Name der Gruppe
ui.admin.users.table.filter.groupname.description=Gruppen anhand des Namens filtern
ui.admin.roles.table.description=Rollen
ui.admin.users.table.filter.rolename.placeholder=Name der Rolle
ui.admin.users.table.filter.rolename.description=Rollen nach Name filtern
ui.admin.pagemodels.table.columns.headers.islive=Ist publiziert?
ui.admin.pagemodels.select_application=Bitte eine Applikation ausw\u00e4hlen

View File

@ -668,7 +668,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name
ui.admin.pagemodels.table.columns.headers.title=Title
ui.admin.pagemodels.table.columns.headers.desc=Description
ui.admin.pagemodels.table.columns.headers.remove=Delete
\ \tui.admin.pagemodels.table.columns.remove.label=Delete
\ ui.admin.pagemodels.table.columns.remove.label=Delete
ui.admin.pagemodels.details.model_name=Name
ui.admin.pagemodels.details.model_title=Titel
ui.admin.pagemodels.details.model_application=Application
@ -677,3 +677,11 @@ ui.admin.pagemodels.details.edit_properties=Edit properties
ui.admin.pagemodels.components.key.label=ID
ui.admin.pagemodels.components.key.error.not_empty=The ID of a component can't be empty.
ui.admin.pagemodels.table.columns.remove.label=Delete
ui.admin.pagemodels.details.publish=(Re-)Publish
ui.admin.users.table.filter.groupname.placeholder=Name of Group
ui.admin.users.table.filter.groupname.description=Filter groups by name
ui.admin.roles.table.description=Roles
ui.admin.users.table.filter.rolename.placeholder=Name of role
ui.admin.users.table.filter.rolename.description=Filter roles by name
ui.admin.pagemodels.table.columns.headers.islive=Is live?
ui.admin.pagemodels.select_application=Please select an application

View File

@ -659,7 +659,7 @@ ui.admin.pagemodels.table.columns.headers.name=Name
ui.admin.pagemodels.table.columns.headers.title=Title
ui.admin.pagemodels.table.columns.headers.desc=Description
ui.admin.pagemodels.table.columns.headers.remove=Delete
\ \tui.admin.pagemodels.table.columns.remove.label=Delete
\ ui.admin.pagemodels.table.columns.remove.label=Delete
ui.admin.pagemodels.details.model_name=Name
ui.admin.pagemodels.details.model_title=Titel
ui.admin.pagemodels.details.model_application=Application
@ -668,3 +668,11 @@ ui.admin.pagemodels.details.edit_properties=Edit properties
ui.admin.pagemodels.components.key.label=ID
ui.admin.pagemodels.components.key.error.not_empty=The ID of a component can't be empty.
ui.admin.pagemodels.table.columns.remove.label=Delete
ui.admin.pagemodels.details.publish=(Re-)Publish
ui.admin.users.table.filter.groupname.placeholder=Name of Group
ui.admin.users.table.filter.groupname.description=Filter groups by name
ui.admin.roles.table.description=Roles
ui.admin.users.table.filter.rolename.placeholder=Name of role
ui.admin.users.table.filter.rolename.description=Filter roles by name
ui.admin.pagemodels.table.columns.headers.islive=Is live?
ui.admin.pagemodels.select_application=Please select an application