CCM NG: Category administration finished

git-svn-id: https://svn.libreccm.org/ccm/ccm_ng@4084 8810af33-2d31-482b-a856-94f89814c4df
pull/2/head
jensp 2016-05-20 19:09:25 +00:00
parent 1111e644c1
commit 196af54d2b
24 changed files with 2142 additions and 286 deletions

View File

@ -33,6 +33,8 @@ import com.arsdigita.bebop.parameters.StringParameter;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.toolbox.ui.LayoutPanel;
import org.libreccm.categorization.Category;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
/**
@ -65,6 +67,13 @@ public class CategoriesTab extends LayoutPanel {
private final Label categoriesTreeHeader;
private final BoxPanel categoriesTreePanel;
private final CategoryDetails categoryDetails;
private final CategoryTitleForm categoryTitleForm;
private final CategoryDescriptionForm categoryDescriptionForm;
private final CategoryCreateForm categoryCreateForm;
private final CategoryEditForm categoryEditForm;
private final CategoryMover categoryMover;
public CategoriesTab() {
super();
@ -72,29 +81,29 @@ public class CategoriesTab extends LayoutPanel {
domainIdParameter = new StringParameter("selected_domain_id");
selectedDomainId = new ParameterSingleSelectionModel<>(
domainIdParameter);
domainIdParameter);
categoryIdParameter = new StringParameter("selected_category_id");
selectedCategoryId = new ParameterSingleSelectionModel<>(
categoryIdParameter);
categoryIdParameter);
languageParameter = new StringParameter("selected_language");
selectedLanguage = new ParameterSingleSelectionModel<>(
languageParameter);
languageParameter);
final SegmentedPanel left = new SegmentedPanel();
domainsFilterFormHeader = new Label(new GlobalizedMessage(
"ui.admin.categories.domains.table.filter.header",
ADMIN_BUNDLE));
"ui.admin.categories.domains.table.filter.header",
ADMIN_BUNDLE));
domainsFilterForm = new Form("domainFilterForm");
final TextField domainsFilter = new TextField(DOMAINS_FILTER);
domainsFilterForm.add(domainsFilter);
domainsFilterForm.add(new Submit(new GlobalizedMessage(
"ui.admin.categories.domains.table.filter", ADMIN_BUNDLE)));
"ui.admin.categories.domains.table.filter", ADMIN_BUNDLE)));
final ActionLink clearLink = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.domains.table.filter.clear",
ADMIN_BUNDLE));
"ui.admin.categories.domains.table.filter.clear",
ADMIN_BUNDLE));
clearLink.addActionListener(e -> {
final PageState state = e.getPageState();
domainsFilter.setValue(state, null);
@ -103,17 +112,29 @@ public class CategoriesTab extends LayoutPanel {
left.addSegment(domainsFilterFormHeader, domainsFilterForm);
categoriesTreeHeader = new Label(new GlobalizedMessage(
"ui.admin.categories.tree.header",
ADMIN_BUNDLE));
"ui.admin.categories.tree.header",
ADMIN_BUNDLE));
categoriesTreePanel = new BoxPanel(BoxPanel.VERTICAL);
final Tree categoriesTree = new Tree(new CategoriesTreeModelBuilder(
selectedDomainId));
categoriesTree.addActionListener(e -> {
selectedDomainId));
categoriesTree.addChangeListener(e -> {
final PageState state = e.getPageState();
selectedCategoryId.setSelectedKey(
state, (String) categoriesTree.getSelectedKey(state));
showCategoryDetails(state);
});
selectedCategoryId.addChangeListener(e -> {
final PageState state = e.getPageState();
categoriesTree.setSelectedKey(state, selectedCategoryId
.getSelectedKey(state));
});
final ActionLink backToDomain = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.tree.back",
ADMIN_BUNDLE));
"ui.admin.categories.tree.back",
ADMIN_BUNDLE));
backToDomain.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTree.getSelectionModel().clearSelection(state);
@ -128,12 +149,12 @@ public class CategoriesTab extends LayoutPanel {
final BoxPanel body = new BoxPanel(BoxPanel.VERTICAL);
final DomainsTable domainsTable = new DomainsTable(
this, selectedDomainId, domainsFilter);
this, selectedDomainId, domainsFilter);
domainsTable.setStyleAttr("min-width: 30em;");
domainsTablePanel = new BoxPanel(BoxPanel.VERTICAL);
domainsTablePanel.add(domainsTable);
final ActionLink addDomain = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.domains.create_new", ADMIN_BUNDLE));
"ui.admin.categories.domains.create_new", ADMIN_BUNDLE));
addDomain.addActionListener(e -> {
showDomainForm(e.getPageState());
});
@ -159,6 +180,33 @@ public class CategoriesTab extends LayoutPanel {
selectedLanguage);
body.add(domainDescriptionForm);
categoryDetails = new CategoryDetails(this,
selectedDomainId,
selectedCategoryId,
selectedLanguage);
body.add(categoryDetails);
categoryTitleForm = new CategoryTitleForm(this,
selectedCategoryId,
selectedLanguage);
body.add(categoryTitleForm);
categoryDescriptionForm = new CategoryDescriptionForm(this,
selectedCategoryId,
selectedLanguage);
body.add(categoryDescriptionForm);
categoryCreateForm = new CategoryCreateForm(this, selectedCategoryId);
body.add(categoryCreateForm);
categoryEditForm = new CategoryEditForm(this, selectedCategoryId);
body.add(categoryEditForm);
categoryMover = new CategoryMover(this,
selectedDomainId,
selectedCategoryId);
body.add(categoryMover);
setBody(body);
}
@ -178,8 +226,16 @@ public class CategoriesTab extends LayoutPanel {
page.setVisibleDefault(domainDetails, false);
page.setVisibleDefault(domainTitleForm, false);
page.setVisibleDefault(domainDescriptionForm, false);
page.setVisibleDefault(categoriesTreeHeader, false);
page.setVisibleDefault(categoriesTreePanel, false);
page.setVisibleDefault(categoryDetails, false);
page.setVisibleDefault(categoryTitleForm, false);
page.setVisibleDefault(categoryDescriptionForm, false);
page.setVisibleDefault(categoryCreateForm, false);
page.setVisibleDefault(categoryEditForm, false);
page.setVisibleDefault(categoryMover, false);
}
protected void showDomainsTable(final PageState state) {
@ -190,9 +246,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void showDomainForm(final PageState state) {
@ -203,8 +266,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideDomainForm(final PageState state) {
@ -216,8 +287,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
} else {
showDomainDetails(state);
}
@ -232,8 +311,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, true);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, true);
categoriesTreePanel.setVisible(state, true);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideDomainDetails(final PageState state) {
@ -246,8 +333,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void showDomainTitleForm(final PageState state) {
@ -258,8 +353,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, true);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideDomainTitleForm(final PageState state) {
@ -276,8 +379,16 @@ public class CategoriesTab extends LayoutPanel {
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, true);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideDomainDescriptionForm(final PageState state) {
@ -287,41 +398,157 @@ public class CategoriesTab extends LayoutPanel {
}
protected void showCategoryDetails(final PageState state) {
domainsFilterFormHeader.setVisible(state, false);
domainsFilterForm.setVisible(state, false);
domainsTablePanel.setVisible(state, false);
domainForm.setVisible(state, false);
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, true);
categoriesTreePanel.setVisible(state, true);
categoryDetails.setVisible(state, true);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideCategoryDetails(final PageState state) {
selectedCategoryId.clearSelection(state);
showDomainDetails(state);
}
protected void showCategoryCreateForm(final PageState state) {
domainsFilterFormHeader.setVisible(state, false);
domainsFilterForm.setVisible(state, false);
domainsTablePanel.setVisible(state, false);
domainForm.setVisible(state, false);
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, true);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideCategoryCreateForm(final PageState state) {
//Show category details of new category (or the selected category if
//creation was canceled
showCategoryDetails(state);
}
protected void showCategoryEditForm(final PageState state) {
domainsFilterFormHeader.setVisible(state, false);
domainsFilterForm.setVisible(state, false);
domainsTablePanel.setVisible(state, false);
domainForm.setVisible(state, false);
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, true);
categoryMover.setVisible(state, false);
}
protected void hideCategoryEditForm(final PageState state) {
//We want to go back to the details of the selected category, therefore
//we don't reset the selection.
showCategoryDetails(state);
}
protected void showCategoryTitleForm(final PageState state) {
domainsFilterFormHeader.setVisible(state, false);
domainsFilterForm.setVisible(state, false);
domainsTablePanel.setVisible(state, false);
domainForm.setVisible(state, false);
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, true);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideCategoryTitleForm(final PageState state) {
selectedLanguage.clearSelection(state);
showCategoryDetails(state);
}
protected void showCategoryDescriptionForm(final PageState state) {
domainsFilterFormHeader.setVisible(state, false);
domainsFilterForm.setVisible(state, false);
domainsTablePanel.setVisible(state, false);
domainForm.setVisible(state, false);
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, true);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, false);
}
protected void hideCategoryDescriptionForm(final PageState state) {
selectedLanguage.clearSelection(state);
showCategoryDetails(state);
}
protected void showCategoryMover(final PageState state) {
domainsFilterFormHeader.setVisible(state, false);
domainsFilterForm.setVisible(state, false);
domainsTablePanel.setVisible(state, false);
domainForm.setVisible(state, false);
domainDetails.setVisible(state, false);
domainTitleForm.setVisible(state, false);
domainDescriptionForm.setVisible(state, false);
categoriesTreeHeader.setVisible(state, false);
categoriesTreePanel.setVisible(state, false);
categoryDetails.setVisible(state, false);
categoryTitleForm.setVisible(state, false);
categoryDescriptionForm.setVisible(state, false);
categoryCreateForm.setVisible(state, false);
categoryEditForm.setVisible(state, false);
categoryMover.setVisible(state, true);
}
protected void hideCategoryMover(final PageState state) {
showCategoryDetails(state);
}
}

View File

@ -23,7 +23,9 @@ import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeNode;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.categorization.Domain;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.Iterator;
import java.util.List;
@ -42,13 +44,20 @@ public class CategoriesTreeModel implements TreeModel {
@Override
public TreeNode getRoot(final PageState data) {
return new CategoryTreeNode(domain.getRoot());
final CategoryRepository categoryRepository = CdiUtil.createCdiUtil()
.findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(domain.getRoot()
.getObjectId());
return new CategoryTreeNode(category);
}
@Override
public boolean hasChildren(final TreeNode node,
final PageState state) {
final Category category = ((CategoryTreeNode) node).getCategory();
final CategoryRepository categoryRepo = CdiUtil.createCdiUtil()
.findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(
((CategoryTreeNode) node).getCategory().getObjectId());
return (category.getSubCategories() != null
&& !category.getSubCategories().isEmpty());
@ -57,8 +66,12 @@ public class CategoriesTreeModel implements TreeModel {
@Override
public Iterator getChildren(final TreeNode node,
final PageState state) {
return new SubCategoryNodesIterator(((CategoryTreeNode) node)
.getCategory().getSubCategories());
final CategoryRepository categoryRepo = CdiUtil.createCdiUtil()
.findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(
((CategoryTreeNode) node).getCategory().getObjectId());
return new SubCategoryNodesIterator(category.getSubCategories());
}
private class CategoryTreeNode implements TreeNode {

View File

@ -0,0 +1,131 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.ui.admin.categories;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.globalization.GlobalizedMessage;
import org.apache.logging.log4j.util.Strings;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryCreateForm extends Form {
private static final String CATEGORY_NAME = "categoryName";
private final ParameterSingleSelectionModel<String> selectedCategoryId;
private final TextField categoryName;
private final SaveCancelSection saveCancelSection;
public CategoryCreateForm(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId) {
super("categoryCreateForm");
this.selectedCategoryId = selectedCategoryId;
final Label heading = new Label(e -> {
final PageState state = e.getPageState();
final Label target = (Label) e.getTarget();
final CategoryRepository categoryRepository = CdiUtil
.createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(Long
.parseLong(selectedCategoryId.getSelectedKey(state)));
target.setLabel(new GlobalizedMessage(
"ui.admin.categories.category.create_new_subcategory",
ADMIN_BUNDLE,
new String[]{category.getName()}));
});
heading.setClassAttr("heading");
add(heading);
categoryName = new TextField(CATEGORY_NAME);
categoryName.setLabel(new GlobalizedMessage(
"ui.admin.categories.category.name.label", ADMIN_BUNDLE));
add(categoryName);
saveCancelSection = new SaveCancelSection();
add(saveCancelSection);
addValidationListener(e -> {
final PageState state = e.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final FormData data = e.getFormData();
final String categoryNameData = data.getString(CATEGORY_NAME);
if (Strings.isBlank(categoryNameData)) {
data.addError(
CATEGORY_NAME,
new GlobalizedMessage(
"ui.admin.categories.category.name.errors.not_blank",
ADMIN_BUNDLE));
}
}
});
addProcessListener(e -> {
final PageState state = e.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepository = cdiUtil.findBean(
CategoryRepository.class);
final CategoryManager categoryManager = cdiUtil.findBean(
CategoryManager.class);
final Category selectedCategory = categoryRepository.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(state)));
final FormData data = e.getFormData();
final String categoryNameData = data.getString(CATEGORY_NAME);
final Category category = new Category();
category.setName(categoryNameData);
categoryRepository.save(category);
categoryManager.addSubCategoryToCategory(category,
selectedCategory);
selectedCategoryId.setSelectedKey(
state, Long.toString(category.getObjectId()));
}
categoriesTab.hideCategoryCreateForm(state);
});
}
}

View File

@ -30,11 +30,10 @@ import com.arsdigita.bebop.form.TextArea;
import com.arsdigita.globalization.GlobalizedMessage;
import java.util.Locale;
import org.apache.logging.log4j.util.Strings;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.categorization.Domain;
import org.libreccm.categorization.DomainRepository;
import org.libreccm.cdi.utils.CdiUtil;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
@ -83,7 +82,7 @@ public class CategoryDescriptionForm extends Form {
final Label target = (Label) e.getTarget();
if (selectedCategory.getTitle().hasValue(selectedLocale)) {
if (selectedCategory.getDescription().hasValue(selectedLocale)) {
target.setLabel(new GlobalizedMessage(
"ui.admin.categories.category.description.edit_for_lang",
ADMIN_BUNDLE,
@ -102,7 +101,7 @@ public class CategoryDescriptionForm extends Form {
description = new TextArea(LOCALIZED_CATEGORY_DESC);
description.setLabel(new GlobalizedMessage(
"ui.admin.categories.domain.description.label", ADMIN_BUNDLE));
"ui.admin.categories.category.description.label", ADMIN_BUNDLE));
description.setCols(60);
description.setRows(10);
add(description);
@ -121,7 +120,7 @@ public class CategoryDescriptionForm extends Form {
final Locale selectedLocale = new Locale(selectedLanguage
.getSelectedKey(state));
if (selectedCategory.getTitle().hasValue(selectedLocale)) {
if (selectedCategory.getDescription().hasValue(selectedLocale)) {
description.setValue(state, selectedCategory.getDescription()
.getValue(selectedLocale));
}

View File

@ -59,9 +59,9 @@ public class CategoryDescriptionTable extends Table {
private final ParameterSingleSelectionModel<String> selectedLanguage;
public CategoryDescriptionTable(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
super();
@ -72,30 +72,30 @@ public class CategoryDescriptionTable extends Table {
setIdAttr("categoryDescriptionTable");
setEmptyView(new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.none",
ADMIN_BUNDLE)));
"ui.admin.categories.category_details.description.none",
ADMIN_BUNDLE)));
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(
COL_LOCALE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_lang",
ADMIN_BUNDLE))));
COL_LOCALE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_lang",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_VALUE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_value",
ADMIN_BUNDLE))));
COL_VALUE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_value",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_del",
ADMIN_BUNDLE))));
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_edit",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_DEL,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_del",
ADMIN_BUNDLE))));
COL_DEL,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.col_del",
ADMIN_BUNDLE))));
columnModel.get(COL_EDIT).setCellRenderer(new TableCellRenderer() {
@ -109,6 +109,7 @@ public class CategoryDescriptionTable extends Table {
final int column) {
return new ControlLink((Component) value);
}
});
columnModel.get(COL_DEL).setCellRenderer(new TableCellRenderer() {
@ -126,15 +127,17 @@ public class CategoryDescriptionTable extends Table {
} else {
final ControlLink link = new ControlLink((Component) value);
link.setConfirmation(new GlobalizedMessage(
"ui.admin.categories.category_details.description"
+ ".del_confirm",
ADMIN_BUNDLE));
"ui.admin.categories.category_details.description"
+ ".del_confirm",
ADMIN_BUNDLE));
return link;
}
}
});
addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event) {
final PageState state = event.getPageState();
@ -147,13 +150,13 @@ public class CategoryDescriptionTable extends Table {
break;
case COL_DEL:
final Locale locale = new Locale((String) event
.getRowKey());
.getRowKey());
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(
CategoryRepository.class);
createCdiUtil().findBean(
CategoryRepository.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.
getSelectedKey(state)));
Long.parseLong(selectedCategoryId.
getSelectedKey(state)));
category.getDescription().removeValue(locale);
categoryRepository.save(category);
@ -166,14 +169,15 @@ public class CategoryDescriptionTable extends Table {
public void headSelected(final TableActionEvent event) {
//Nothing
}
});
setModelBuilder(new CategoryDescriptionTableModelBuilder());
}
private class CategoryDescriptionTableModelBuilder
extends LockableImpl
implements TableModelBuilder {
extends LockableImpl
implements TableModelBuilder {
@Override
public TableModel makeModel(final Table table,
@ -182,6 +186,7 @@ public class CategoryDescriptionTable extends Table {
return new CategoryDescriptionTableModel(state);
}
}
private class CategoryDescriptionTableModel implements TableModel {
@ -192,13 +197,15 @@ public class CategoryDescriptionTable extends Table {
public CategoryDescriptionTableModel(final PageState state) {
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
createCdiUtil().findBean(CategoryRepository.class);
selectedCategory = categoryRepository.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
selectedCategoryId.getSelectedKey(state)));
locales = new ArrayList<>();
locales.addAll(selectedCategory.getDescription().
getAvailableLocales());
if (selectedCategory.getDescription() != null) {
locales.addAll(
selectedCategory.getDescription().getAvailableLocales());
}
locales.sort((l1, l2) -> {
return l1.toString().compareTo(l2.toString());
});
@ -227,15 +234,15 @@ public class CategoryDescriptionTable extends Table {
return selectedCategory.getDescription().getValue(locale);
case COL_EDIT:
return new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.edit",
ADMIN_BUNDLE));
"ui.admin.categories.category_details.description.edit",
ADMIN_BUNDLE));
case COL_DEL:
return new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description.del",
ADMIN_BUNDLE));
"ui.admin.categories.category_details.description.del",
ADMIN_BUNDLE));
default:
throw new IllegalArgumentException(
"Not a valid column index");
"Not a valid column index");
}
}
@ -245,4 +252,5 @@ public class CategoryDescriptionTable extends Table {
}
}
}

View File

@ -55,12 +55,13 @@ class CategoryDetails extends SegmentedPanel {
private final ParameterSingleSelectionModel<String> selectedLanguage;
private final CategoryTitleAddForm categoryTitleAddForm;
private final CategoryDescriptionAddForm categoryDescriptionAddForm;
private final SubCategoriesTable subCategoriesTable;
public CategoryDetails(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedDomainId,
final ParameterSingleSelectionModel<String> selectedCategoryId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedDomainId,
final ParameterSingleSelectionModel<String> selectedCategoryId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
this.categoriesTab = categoriesTab;
this.selectedDomainId = selectedDomainId;
@ -68,43 +69,86 @@ class CategoryDetails extends SegmentedPanel {
this.selectedLanguage = selectedLanguage;
final ActionLink backLink = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.category_details.back", ADMIN_BUNDLE));
"ui.admin.categories.category_details.back", ADMIN_BUNDLE));
backLink.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTab.hideCategoryDetails(state);
});
addSegment("category-details-back", backLink);
final Label heading = new Label(e -> {
final PageState state = e.getPageState();
final Label target = (Label) e.getTarget();
final CategoryRepository categoryRepo = CdiUtil.createCdiUtil()
.findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
target.setLabel(new GlobalizedMessage(
"ui.admin.categories.category_details.heading",
ADMIN_BUNDLE,
new String[]{category.getName()}));
});
heading.setClassAttr("heading");
add(heading);
final BoxPanel propertiesPanel = new BoxPanel(BoxPanel.VERTICAL);
propertiesPanel.add(new PropertySheet(
new CategoryPropertySheetModelBuilder(selectedCategoryId)));
new CategoryPropertySheetModelBuilder(selectedCategoryId)));
final ActionLink editBasicPropertiesLink = new ActionLink(
new GlobalizedMessage(
"ui.admin.categories.category_details.basic_properties.edit",
ADMIN_BUNDLE));
new GlobalizedMessage(
"ui.admin.categories.category_details.basic_properties.edit",
ADMIN_BUNDLE));
editBasicPropertiesLink.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTab.showCategoryEditForm(state);
});
propertiesPanel.add(editBasicPropertiesLink);
final ActionLink moveLink = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.category_details.move_category", ADMIN_BUNDLE)) {
@Override
public boolean isVisible(final PageState state) {
if (super.isVisible(state)) {
final CategoryRepository categoryRepo = CdiUtil
.createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(Long
.parseLong(selectedCategoryId.getSelectedKey(state)));
//If the category has no parent category it is the root
//category of a domain and can't be moved
return category.getParentCategory() != null;
} else {
return false;
}
}
};
moveLink.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTab.showCategoryMover(state);
});
propertiesPanel.add(moveLink);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.basic_properties",
ADMIN_BUNDLE)),
propertiesPanel
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.basic_properties",
ADMIN_BUNDLE)),
propertiesPanel
);
final BoxPanel titlesPanel = new BoxPanel(BoxPanel.VERTICAL);
titlesPanel.add(new CategoryTitleTable(categoriesTab,
selectedDomainId,
selectedCategoryId,
selectedLanguage));
categoryTitleAddForm = new CategoryTitleAddForm();
titlesPanel.add(categoryTitleAddForm);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_title",
ADMIN_BUNDLE)),
titlesPanel);
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.category_title",
ADMIN_BUNDLE)),
titlesPanel);
final BoxPanel descPanel = new BoxPanel(BoxPanel.VERTICAL);
descPanel.add(new CategoryDescriptionTable(categoriesTab,
@ -113,10 +157,29 @@ class CategoryDetails extends SegmentedPanel {
categoryDescriptionAddForm = new CategoryDescriptionAddForm();
descPanel.add(categoryDescriptionAddForm);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description",
ADMIN_BUNDLE)),
descPanel);
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.description",
ADMIN_BUNDLE)),
descPanel);
final BoxPanel subCategoriesPanel = new BoxPanel(BoxPanel.VERTICAL);
subCategoriesTable = new SubCategoriesTable(categoriesTab,
selectedCategoryId);
subCategoriesPanel.add(subCategoriesTable);
final ActionLink addSubCategory = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.category_details.subcategories.add",
ADMIN_BUNDLE));
addSubCategory.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTab.showCategoryCreateForm(state);
});
subCategoriesPanel.add(addSubCategory);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.subcategories.header",
ADMIN_BUNDLE)),
subCategoriesPanel);
}
private class CategoryTitleAddForm extends Form {
@ -127,22 +190,22 @@ class CategoryDetails extends SegmentedPanel {
super("categoryTitleAddForm", new BoxPanel(BoxPanel.HORIZONTAL));
final SingleSelect titleSelectLang = new SingleSelect(
TITLE_SELECT_LANG);
TITLE_SELECT_LANG);
titleSelectLang.setLabel(new GlobalizedMessage(
"ui.admin.categories.category_details.category_title.add.label",
ADMIN_BUNDLE));
"ui.admin.categories.category_details.category_title.add.label",
ADMIN_BUNDLE));
try {
titleSelectLang.addPrintListener(e -> {
final PageState state = e.getPageState();
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig.
getSupportedLanguages();
getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
category.getTitle().getAvailableLocales().forEach(l -> {
assignedLanguages.add(l.toString());
@ -164,8 +227,8 @@ class CategoryDetails extends SegmentedPanel {
add(titleSelectLang);
add(new Submit(new GlobalizedMessage(
"ui.admin.categories.category_details.category_title.add.submit",
ADMIN_BUNDLE)));
"ui.admin.categories.category_details.category_title.add.submit",
ADMIN_BUNDLE)));
addProcessListener(e -> {
final PageState state = e.getPageState();
@ -182,13 +245,13 @@ class CategoryDetails extends SegmentedPanel {
public boolean isVisible(final PageState state) {
if (super.isVisible(state)) {
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig.
getSupportedLanguages();
getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
category.getTitle().getAvailableLocales().forEach(l -> {
assignedLanguages.add(l.toString());
@ -201,6 +264,7 @@ class CategoryDetails extends SegmentedPanel {
return false;
}
}
}
private class CategoryDescriptionAddForm extends Form {
@ -211,27 +275,27 @@ class CategoryDetails extends SegmentedPanel {
super("categoryAddDescLang", new BoxPanel(BoxPanel.HORIZONTAL));
final SingleSelect descSelectLang = new SingleSelect(
DESC_SELECT_LANG);
DESC_SELECT_LANG);
descSelectLang.setLabel(new GlobalizedMessage(
"ui.admin.categories.category_details.category_desc.add.label",
ADMIN_BUNDLE));
"ui.admin.categories.category_details.category_desc.add.label",
ADMIN_BUNDLE));
try {
descSelectLang.addPrintListener(e -> {
final PageState state = e.getPageState();
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig.
getSupportedLanguages();
getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
category.getDescription().getAvailableLocales().forEach(
l -> {
assignedLanguages.add(l.toString());
});
l -> {
assignedLanguages.add(l.toString());
});
final SingleSelect target = (SingleSelect) e.getTarget();
@ -250,8 +314,8 @@ class CategoryDetails extends SegmentedPanel {
add(descSelectLang);
add(new Submit(new GlobalizedMessage(
"ui.admin.categories.category_details.category_desc.add.submit",
ADMIN_BUNDLE)));
"ui.admin.categories.category_details.category_desc.add.submit",
ADMIN_BUNDLE)));
addProcessListener(e -> {
final PageState state = e.getPageState();
@ -268,18 +332,18 @@ class CategoryDetails extends SegmentedPanel {
public boolean isVisible(final PageState state) {
if (super.isVisible(state)) {
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig.
getSupportedLanguages();
getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
category.getDescription().getAvailableLocales().forEach(
l -> {
assignedLanguages.add(l.toString());
});
l -> {
assignedLanguages.add(l.toString());
});
//If all supported languages are assigned the form is not
//visible
@ -288,6 +352,7 @@ class CategoryDetails extends SegmentedPanel {
return false;
}
}
}
}

View File

@ -0,0 +1,184 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.ui.admin.categories;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.FormData;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.form.CheckboxGroup;
import com.arsdigita.bebop.form.Option;
import com.arsdigita.bebop.form.TextField;
import com.arsdigita.globalization.GlobalizedMessage;
import org.apache.logging.log4j.util.Strings;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryEditForm extends Form {
private static final String CATEGORY_NAME = "categoryName";
private static final String CATEGORY_PROPERTIES = "categoryProperties";
private static final String ENABLED = "enabled";
private static final String VISIBLE = "visible";
private static final String ABSTRACT = "abstract";
private final ParameterSingleSelectionModel<String> selectedCategoryId;
private final TextField categoryName;
private final CheckboxGroup properties;
private final SaveCancelSection saveCancelSection;
public CategoryEditForm(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId) {
super("categoryEditForm");
this.selectedCategoryId = selectedCategoryId;
final Label heading = new Label(e -> {
final PageState state = e.getPageState();
final Label target = (Label) e.getTarget();
final CategoryRepository categoryRepository = CdiUtil
.createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(Long
.parseLong(selectedCategoryId.getSelectedKey(state)));
target.setLabel(new GlobalizedMessage(
"ui.admin.categories.category.edit_category",
ADMIN_BUNDLE,
new String[]{category.getName()}));
});
heading.setClassAttr("heading");
add(heading);
categoryName = new TextField(CATEGORY_NAME);
categoryName.setLabel(new GlobalizedMessage(
"ui.admin.categories.category.name.label", ADMIN_BUNDLE));
add(categoryName);
properties = new CheckboxGroup(CATEGORY_PROPERTIES);
properties.addOption(new Option(
ENABLED,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.name.enabled",
ADMIN_BUNDLE))));
properties.addOption(new Option(
VISIBLE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.name.visible",
ADMIN_BUNDLE))));
properties.addOption(new Option(
ABSTRACT,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.name.abstract",
ADMIN_BUNDLE))));
add(properties);
saveCancelSection = new SaveCancelSection();
add(saveCancelSection);
addInitListener(e -> {
final PageState state = e.getPageState();
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepository = cdiUtil.findBean(
CategoryRepository.class);
final Category category = categoryRepository.findById(Long
.parseLong(selectedCategoryId.getSelectedKey(state)));
categoryName.setValue(state, category.getName());
final List<String> props = new ArrayList<>();
if (category.isEnabled()) {
props.add(ENABLED);
}
if (category.isVisible()) {
props.add(VISIBLE);
}
if (category.isAbstractCategory()) {
props.add(ABSTRACT);
}
properties.setValue(state, props.toArray(new String[props.size()]));
});
addValidationListener(e -> {
final PageState state = e.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final FormData data = e.getFormData();
final String categoryNameData = data.getString(CATEGORY_NAME);
if (Strings.isBlank(categoryNameData)) {
data.addError(
CATEGORY_NAME,
new GlobalizedMessage(
"ui.admin.categories.category.name.errors.not_blank",
ADMIN_BUNDLE));
}
}
});
addProcessListener(e -> {
final PageState state = e.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepository = cdiUtil.findBean(
CategoryRepository.class);
final CategoryManager categoryManager = cdiUtil.findBean(
CategoryManager.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(state)));
final FormData data = e.getFormData();
final String categoryNameData = data.getString(CATEGORY_NAME);
category.setName(categoryNameData);
final List<String> propertiesData = Arrays.asList((String[]) data.get(
CATEGORY_PROPERTIES));
category.setEnabled(propertiesData.contains(ENABLED));
category.setVisible(propertiesData.contains(VISIBLE));
category.setAbstractCategory(propertiesData.contains(ABSTRACT));
categoryRepository.save(category);
}
categoriesTab.hideCategoryEditForm(state);
});
}
}

View File

@ -0,0 +1,110 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.ui.admin.categories;
import com.arsdigita.bebop.BoxPanel;
import com.arsdigita.bebop.Form;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.SaveCancelSection;
import com.arsdigita.bebop.Tree;
import com.arsdigita.globalization.GlobalizedMessage;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryManager;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.cdi.utils.CdiUtil;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryMover extends Form {
private final CategoriesTab categoriesTab;
private final ParameterSingleSelectionModel<String> selectedDomainId;
private final ParameterSingleSelectionModel<String> selectedCategoryId;
private final Tree categoryTree;
private final SaveCancelSection saveCancelSection;
public CategoryMover(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedDomainId,
final ParameterSingleSelectionModel<String> selectedCategoryId) {
super("categoryMover", new BoxPanel(BoxPanel.VERTICAL));
this.categoriesTab = categoriesTab;
this.selectedDomainId = selectedDomainId;
this.selectedCategoryId = selectedCategoryId;
final Label heading = new Label(e -> {
final PageState state = e.getPageState();
final Label target = (Label) e.getTarget();
final CategoryRepository categoryRepo = CdiUtil
.createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
target.setLabel(new GlobalizedMessage(
"ui.admin.categories.category.move.heading",
ADMIN_BUNDLE,
new String[]{category.getName()}));
});
heading.setClassAttr("heading");
add(heading);
categoryTree = new Tree(new CategoryMoverModelBuilder(
selectedDomainId, selectedCategoryId));
add(categoryTree);
saveCancelSection = new SaveCancelSection();
add(saveCancelSection);
addProcessListener(e -> {
final PageState state = e.getPageState();
if (saveCancelSection.getSaveButton().isSelected(state)) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil.findBean(
CategoryRepository.class);
final CategoryManager categoryManager = cdiUtil.findBean(
CategoryManager.class);
final Category category = categoryRepo.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
final Category parent = category.getParentCategory();
final Category target = categoryRepo.findById(Long.parseLong(
(String) categoryTree.getSelectedKey(state)));
categoryManager.removeSubCategoryFromCategory(category, parent);
categoryManager.addSubCategoryToCategory(category, target);
}
categoriesTab.hideCategoryMover(state);
});
}
}

View File

@ -0,0 +1,142 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.ui.admin.categories;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeNode;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.categorization.Domain;
import org.libreccm.cdi.utils.CdiUtil;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryMoverModel implements TreeModel {
private final Domain domain;
private final Category selectedCategory;
public CategoryMoverModel(final Domain domain,
final Category selectedCategory) {
this.domain = domain;
this.selectedCategory = selectedCategory;
}
@Override
public TreeNode getRoot(final PageState data) {
final CategoryRepository categoryRepository = CdiUtil.createCdiUtil()
.findBean(CategoryRepository.class);
final Category category = categoryRepository.findById(domain.getRoot()
.getObjectId());
return new CategoryMoverNode(category);
}
/**
* Creates a list of the sub categories of the provided node
* <em>without</em>
* the selected category. This prevents the selected category and its sub
* categories from be added to tree. Therefore the user can't move a
* category beneath itself.
*
* @param node The current node.
*
* @return A list of the subcategories of the category managed by the
* provided node.
*/
private List<Category> getSubCategories(final TreeNode node) {
final CategoryRepository categoryRepo = CdiUtil.createCdiUtil()
.findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(
((CategoryMoverNode) node).getCategory().getObjectId());
final List<Category> subCategories = new ArrayList<>();
category.getSubCategories().forEach(c -> {
if (!c.equals(selectedCategory)) {
subCategories.add(c);
}
});
return subCategories;
}
@Override
public boolean hasChildren(final TreeNode node, final PageState state) {
final List<Category> subCategories = getSubCategories(node);
return (subCategories != null && !subCategories.isEmpty()) ;
}
@Override
public Iterator getChildren(final TreeNode node, final PageState state) {
return new SubCategoryNodesIterator(getSubCategories(node));
}
private class CategoryMoverNode implements TreeNode {
private final Category category;
public CategoryMoverNode(final Category category) {
this.category = category;
}
public Category getCategory() {
return category;
}
@Override
public Object getKey() {
return Long.toString(category.getObjectId());
}
@Override
public Object getElement() {
return category.getName();
}
}
private class SubCategoryNodesIterator
implements Iterator<CategoryMoverNode> {
private final Iterator<Category> subCategoriesIterator;
public SubCategoryNodesIterator(final List<Category> subCategories) {
subCategoriesIterator = subCategories.iterator();
}
@Override
public boolean hasNext() {
return subCategoriesIterator.hasNext();
}
@Override
public CategoryMoverNode next() {
return new CategoryMoverNode(subCategoriesIterator.next());
}
}
}

View File

@ -0,0 +1,71 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.ui.admin.categories;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.Tree;
import com.arsdigita.bebop.tree.TreeModel;
import com.arsdigita.bebop.tree.TreeModelBuilder;
import com.arsdigita.util.LockableImpl;
import org.libreccm.categorization.Category;
import org.libreccm.categorization.CategoryRepository;
import org.libreccm.categorization.Domain;
import org.libreccm.categorization.DomainRepository;
import org.libreccm.cdi.utils.CdiUtil;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class CategoryMoverModelBuilder
extends LockableImpl
implements TreeModelBuilder {
private final ParameterSingleSelectionModel<String> selectedDomainId;
private final ParameterSingleSelectionModel<String> selectedCategoryId;
public CategoryMoverModelBuilder(
final ParameterSingleSelectionModel<String> selectedDomainId,
final ParameterSingleSelectionModel<String> selectedCategoryId) {
this.selectedDomainId = selectedDomainId;
this.selectedCategoryId = selectedCategoryId;
}
@Override
public TreeModel makeModel(final Tree tree, final PageState state) {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final DomainRepository domainRepository = cdiUtil.findBean(
DomainRepository.class);
final Domain domain = domainRepository.findById(Long.parseLong(
selectedDomainId.getSelectedKey(state)));
final CategoryRepository categoryRepository = cdiUtil.findBean(
CategoryRepository.class);
final Category category = categoryRepository.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
return new CategoryMoverModel(domain, category);
}
}

View File

@ -33,7 +33,10 @@ import static com.arsdigita.ui.admin.AdminUiConstants.*;
public class CategoryPropertySheetModel implements PropertySheetModel {
private static enum CategoryProperty {
NAME
NAME,
ENABLED,
VISIBLE,
ABSTRACT
}
private final Category selectedCategory;
@ -84,9 +87,15 @@ public class CategoryPropertySheetModel implements PropertySheetModel {
switch (currentProperty) {
case NAME:
return selectedCategory.getName();
case ENABLED:
return Boolean.toString(selectedCategory.isEnabled());
case VISIBLE:
return Boolean.toString(selectedCategory.isVisible());
case ABSTRACT:
return Boolean.toString(selectedCategory.isAbstractCategory());
default:
return "";
}
}
}

View File

@ -59,9 +59,9 @@ public class CategoryTitleTable extends Table {
private final ParameterSingleSelectionModel<String> selectedLanguage;
public CategoryTitleTable(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
super();
@ -72,29 +72,29 @@ public class CategoryTitleTable extends Table {
setIdAttr("categoryTitleTable");
setEmptyView(new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.none", ADMIN_BUNDLE)));
"ui.admin.categories.category_details.title.none", ADMIN_BUNDLE)));
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(
COL_LOCALE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_lang",
ADMIN_BUNDLE))));
COL_LOCALE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_lang",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_VALUE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_value",
ADMIN_BUNDLE))));
COL_VALUE,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_value",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_edit",
ADMIN_BUNDLE))));
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_edit",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_DEL,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_del",
ADMIN_BUNDLE))));
COL_DEL,
new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.col_del",
ADMIN_BUNDLE))));
columnModel.get(COL_EDIT).setCellRenderer(new TableCellRenderer() {
@ -126,14 +126,16 @@ public class CategoryTitleTable extends Table {
} else {
final ControlLink link = new ControlLink((Component) value);
link.setConfirmation(new GlobalizedMessage(
"ui.admin.categories.category_details.title.del_confirm",
ADMIN_BUNDLE));
"ui.admin.categories.category_details.title.del_confirm",
ADMIN_BUNDLE));
return link;
}
}
});
addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event) {
final PageState state = event.getPageState();
@ -146,13 +148,13 @@ public class CategoryTitleTable extends Table {
break;
case COL_DEL:
final Locale locale = new Locale((String) event.
getRowKey());
getRowKey());
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(
CategoryRepository.class);
createCdiUtil().findBean(
CategoryRepository.class);
final Category category = categoryRepository.findById(
Long.parseLong(selectedCategoryId.
getSelectedKey(state)));
Long.parseLong(selectedCategoryId.
getSelectedKey(state)));
category.getTitle().removeValue(locale);
categoryRepository.save(category);
@ -165,6 +167,7 @@ public class CategoryTitleTable extends Table {
public void headSelected(final TableActionEvent event) {
//Nothing
}
});
setModelBuilder(new CategoryTitleTableModelBuilder());
@ -172,12 +175,11 @@ public class CategoryTitleTable extends Table {
}
private class CategoryTitleTableModelBuilder
extends LockableImpl
implements TableModelBuilder {
extends LockableImpl
implements TableModelBuilder {
@Override
public TableModel makeModel(final Table table,
final PageState state) {
public TableModel makeModel(final Table table, final PageState state) {
table.getRowSelectionModel().clearSelection(state);
return new CategoryTitleTableModel(state);
@ -193,12 +195,15 @@ public class CategoryTitleTable extends Table {
public CategoryTitleTableModel(final PageState state) {
final CategoryRepository categoryRepository = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
createCdiUtil().findBean(CategoryRepository.class);
selectedCategory = categoryRepository.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
selectedCategoryId.getSelectedKey(state)));
locales = new ArrayList<>();
locales.addAll(selectedCategory.getTitle().getAvailableLocales());
if (selectedCategory.getTitle() != null) {
locales.addAll(
selectedCategory.getTitle().getAvailableLocales());
}
locales.sort((l1, l2) -> {
return l1.toString().compareTo(l2.toString());
});
@ -226,17 +231,17 @@ public class CategoryTitleTable extends Table {
return selectedCategory.getTitle().getValue(locale);
case COL_EDIT:
return new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.edit",
ADMIN_BUNDLE
"ui.admin.categories.category_details.title.edit",
ADMIN_BUNDLE
));
case COL_DEL:
return new Label(new GlobalizedMessage(
"ui.admin.categories.category_details.title.del",
ADMIN_BUNDLE
"ui.admin.categories.category_details.title.del",
ADMIN_BUNDLE
));
default:
throw new IllegalArgumentException(
"Not a valid column index");
"Not a valid column index");
}
}

View File

@ -91,7 +91,7 @@ class DomainDescriptionTable extends Table {
columnModel.add(new TableColumn(
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.description.col_del",
"ui.admin.categories.domain_details.description.col_edit",
ADMIN_BUNDLE))));
columnModel.add(new TableColumn(
COL_DEL,

View File

@ -58,39 +58,56 @@ class DomainDetails extends SegmentedPanel {
private final DomainDescriptionAddForm domainDescriptionAddForm;
public DomainDetails(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedDomainId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedDomainId,
final ParameterSingleSelectionModel<String> selectedLanguage) {
this.categoriesTab = categoriesTab;
this.selectedDomainId = selectedDomainId;
this.selectedLanguage = selectedLanguage;
final ActionLink backLink = new ActionLink(new GlobalizedMessage(
"ui.admin.categories.domain_details.back", ADMIN_BUNDLE));
"ui.admin.categories.domain_details.back", ADMIN_BUNDLE));
backLink.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTab.hideDomainDetails(state);
});
addSegment("domain-details-back", backLink);
final Label heading = new Label(e -> {
final PageState state = e.getPageState();
final Label target = (Label) e.getTarget();
final DomainRepository domainRepository = CdiUtil.createCdiUtil()
.findBean(DomainRepository.class);
final Domain domain = domainRepository.findById(Long.parseLong(
selectedDomainId.getSelectedKey(state)));
target.setLabel(new GlobalizedMessage(
"ui.admin.categories.domain.details.heading",
ADMIN_BUNDLE,
new String[]{domain.getDomainKey()}));
});
heading.setClassAttr("heading");
add(heading);
final BoxPanel propertiesPanel = new BoxPanel(BoxPanel.VERTICAL);
propertiesPanel.add(new PropertySheet(
new DomainPropertySheetModelBuilder(selectedDomainId)));
new DomainPropertySheetModelBuilder(selectedDomainId)));
final ActionLink editBasicPropertiesLink = new ActionLink(
new GlobalizedMessage(
"ui.admin.categories.domain_details.basic_properties.edit",
ADMIN_BUNDLE));
new GlobalizedMessage(
"ui.admin.categories.domain_details.basic_properties.edit",
ADMIN_BUNDLE));
editBasicPropertiesLink.addActionListener(e -> {
final PageState state = e.getPageState();
categoriesTab.showDomainForm(state);
});
propertiesPanel.add(editBasicPropertiesLink);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.basic_properties",
ADMIN_BUNDLE)),
propertiesPanel);
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.basic_properties",
ADMIN_BUNDLE)),
propertiesPanel);
final BoxPanel titlesPanel = new BoxPanel(BoxPanel.VERTICAL);
titlesPanel.add(new DomainTitleTable(categoriesTab,
@ -99,10 +116,10 @@ class DomainDetails extends SegmentedPanel {
domainTitleAddForm = new DomainTitleAddForm();
titlesPanel.add(domainTitleAddForm);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_title",
ADMIN_BUNDLE)),
titlesPanel);
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_title",
ADMIN_BUNDLE)),
titlesPanel);
final BoxPanel descPanel = new BoxPanel(BoxPanel.VERTICAL);
descPanel.add(new DomainDescriptionTable(categoriesTab,
@ -111,20 +128,20 @@ class DomainDetails extends SegmentedPanel {
domainDescriptionAddForm = new DomainDescriptionAddForm();
descPanel.add(domainDescriptionAddForm);
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.description",
ADMIN_BUNDLE)),
descPanel);
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.description",
ADMIN_BUNDLE)),
descPanel);
final BoxPanel mappingsPanel = new BoxPanel(BoxPanel.VERTICAL);
mappingsPanel.add(new DomainMappingsTable(categoriesTab,
selectedDomainId));
mappingsPanel.add(new DomainMappingAddForm(selectedDomainId));
addSegment(
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.mappings",
ADMIN_BUNDLE)),
mappingsPanel);
new Label(new GlobalizedMessage(
"ui.admin.categories.domain_details.mappings",
ADMIN_BUNDLE)),
mappingsPanel);
}
private class DomainTitleAddForm extends Form {
@ -135,21 +152,21 @@ class DomainDetails extends SegmentedPanel {
super("domainAddTitleLang", new BoxPanel(BoxPanel.HORIZONTAL));
final SingleSelect titleSelectLang = new SingleSelect(
TITLE_SELECT_LANG);
TITLE_SELECT_LANG);
titleSelectLang.setLabel(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_title.add.label",
ADMIN_BUNDLE));
"ui.admin.categories.domain_details.domain_title.add.label",
ADMIN_BUNDLE));
try {
titleSelectLang.addPrintListener(e -> {
final PageState state = e.getPageState();
final DomainRepository domainRepository = CdiUtil
.createCdiUtil().findBean(DomainRepository.class);
.createCdiUtil().findBean(DomainRepository.class);
final Domain domain = domainRepository.findById(Long
.parseLong(selectedDomainId.getSelectedKey(state)));
.parseLong(selectedDomainId.getSelectedKey(state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig
.getSupportedLanguages();
.getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
domain.getTitle().getAvailableLocales().forEach(l -> {
assignedLanguages.add(l.toString());
@ -171,8 +188,8 @@ class DomainDetails extends SegmentedPanel {
add(titleSelectLang);
add(new Submit(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_title.add.submit",
ADMIN_BUNDLE)));
"ui.admin.categories.domain_details.domain_title.add.submit",
ADMIN_BUNDLE)));
addProcessListener(e -> {
final PageState state = e.getPageState();
@ -189,13 +206,13 @@ class DomainDetails extends SegmentedPanel {
public boolean isVisible(final PageState state) {
if (super.isVisible(state)) {
final DomainRepository domainRepository = CdiUtil
.createCdiUtil().findBean(DomainRepository.class);
.createCdiUtil().findBean(DomainRepository.class);
final Domain domain = domainRepository.findById(Long
.parseLong(
selectedDomainId.getSelectedKey(state)));
.parseLong(
selectedDomainId.getSelectedKey(state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig
.getSupportedLanguages();
.getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
domain.getTitle().getAvailableLocales().forEach(l -> {
assignedLanguages.add(l.toString());
@ -219,22 +236,22 @@ class DomainDetails extends SegmentedPanel {
super("domainAddDescLang", new BoxPanel(BoxPanel.HORIZONTAL));
final SingleSelect descSelectLang = new SingleSelect(
DESC_SELECT_LANG);
DESC_SELECT_LANG);
descSelectLang.setLabel(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_desc.add.label",
ADMIN_BUNDLE));
"ui.admin.categories.domain_details.domain_desc.add.label",
ADMIN_BUNDLE));
try {
descSelectLang.addPrintListener(e -> {
final PageState state = e.getPageState();
final DomainRepository domainRepository = CdiUtil
.createCdiUtil().findBean(DomainRepository.class);
.createCdiUtil().findBean(DomainRepository.class);
final Domain domain = domainRepository.findById(Long
.parseLong(
selectedDomainId.getSelectedKey(state)));
.parseLong(
selectedDomainId.getSelectedKey(state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig
.getSupportedLanguages();
.getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
domain.getDescription().getAvailableLocales().forEach(l -> {
assignedLanguages.add(l.toString());
@ -256,8 +273,8 @@ class DomainDetails extends SegmentedPanel {
add(descSelectLang);
add(new Submit(new GlobalizedMessage(
"ui.admin.categories.domain_details.domain_desc.add.submit",
ADMIN_BUNDLE)));
"ui.admin.categories.domain_details.domain_desc.add.submit",
ADMIN_BUNDLE)));
addProcessListener(e -> {
final PageState state = e.getPageState();
@ -275,13 +292,13 @@ class DomainDetails extends SegmentedPanel {
public boolean isVisible(final PageState state) {
if (super.isVisible(state)) {
final DomainRepository domainRepository = CdiUtil
.createCdiUtil().findBean(DomainRepository.class);
.createCdiUtil().findBean(DomainRepository.class);
final Domain domain = domainRepository.findById(Long
.parseLong(
selectedDomainId.getSelectedKey(state)));
.parseLong(
selectedDomainId.getSelectedKey(state)));
final KernelConfig kernelConfig = KernelConfig.getConfig();
final Set<String> supportedLanguages = kernelConfig
.getSupportedLanguages();
.getSupportedLanguages();
final Set<String> assignedLanguages = new HashSet<>();
domain.getDescription().getAvailableLocales().forEach(l -> {
assignedLanguages.add(l.toString());
@ -295,5 +312,7 @@ class DomainDetails extends SegmentedPanel {
return false;
}
}
}
}

View File

@ -61,6 +61,7 @@ class DomainForm extends Form {
public DomainForm(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedDomainId) {
super("domainForm");
this.selectedDomainId = selectedDomainId;

View File

@ -0,0 +1,350 @@
/*
* Copyright (C) 2016 LibreCCM Foundation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301 USA
*/
package com.arsdigita.ui.admin.categories;
import com.arsdigita.bebop.Component;
import com.arsdigita.bebop.ControlLink;
import com.arsdigita.bebop.Label;
import com.arsdigita.bebop.PageState;
import com.arsdigita.bebop.ParameterSingleSelectionModel;
import com.arsdigita.bebop.Table;
import com.arsdigita.bebop.Text;
import com.arsdigita.bebop.event.TableActionEvent;
import com.arsdigita.bebop.event.TableActionListener;
import com.arsdigita.bebop.table.TableCellRenderer;
import com.arsdigita.bebop.table.TableColumn;
import com.arsdigita.bebop.table.TableColumnModel;
import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.table.TableModelBuilder;
import com.arsdigita.globalization.GlobalizedMessage;
import com.arsdigita.util.LockableImpl;
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 java.util.ArrayList;
import java.util.List;
import static com.arsdigita.ui.admin.AdminUiConstants.*;
/**
*
* @author <a href="mailto:jens.pelzetter@googlemail.com">Jens Pelzetter</a>
*/
public class SubCategoriesTable extends Table {
private static final int COL_NAME = 0;
private static final int COL_UP = 1;
private static final int COL_DOWN = 2;
private static final int COL_EDIT = 3;
private static final int COL_DEL = 4;
private final CategoriesTab categoriesTab;
private final ParameterSingleSelectionModel<String> selectedCategoryId;
public SubCategoriesTable(
final CategoriesTab categoriesTab,
final ParameterSingleSelectionModel<String> selectedCategoryId) {
super();
this.categoriesTab = categoriesTab;
this.selectedCategoryId = selectedCategoryId;
setIdAttr("subCategoriesTable");
setEmptyView(new Label(new GlobalizedMessage(
"ui.admin.categories.category.no_subcategories",
ADMIN_BUNDLE)));
final TableColumnModel columnModel = getColumnModel();
columnModel.add(new TableColumn(
COL_NAME,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.col_name",
ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_UP,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.col_up",
ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_DOWN,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.col_down",
ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_EDIT,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.col_edit",
ADMIN_BUNDLE))
));
columnModel.add(new TableColumn(
COL_DEL,
new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.col_del",
ADMIN_BUNDLE))
));
columnModel.get(COL_UP).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
if (value == null) {
return new Text("");
} else {
return new ControlLink((Component) value);
}
}
});
columnModel.get(COL_DOWN).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
if (value == null) {
return new Text("");
} else {
return new ControlLink((Component) value);
}
}
});
columnModel.get(COL_EDIT).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
return new ControlLink((Component) value);
}
});
columnModel.get(COL_DEL).setCellRenderer(new TableCellRenderer() {
@Override
public Component getComponent(final Table table,
final PageState state,
final Object value,
final boolean isSelected,
final Object key,
final int row,
final int column) {
if (value == null) {
return new Text("");
} else {
final ControlLink link = new ControlLink((Component) value);
link.setConfirmation(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.del_confirm",
ADMIN_BUNDLE));
return link;
}
}
});
addTableActionListener(new TableActionListener() {
@Override
public void cellSelected(final TableActionEvent event) {
final PageState state = event.getPageState();
switch (event.getColumn()) {
case COL_UP: {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil
.findBean(CategoryRepository.class);
final CategoryManager categoryManager = cdiUtil
.findBean(CategoryManager.class);
final Category parentCategory = categoryRepo.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
final Category subCategory = categoryRepo.findById(Long
.parseLong((String) event.getRowKey()));
categoryManager.decreaseCategoryOrder(subCategory,
parentCategory);
break;
}
case COL_DOWN: {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil
.findBean(CategoryRepository.class);
final CategoryManager categoryManager = cdiUtil
.findBean(CategoryManager.class);
final Category parentCategory = categoryRepo.findById(
Long.parseLong(selectedCategoryId.getSelectedKey(
state)));
final Category subCategory = categoryRepo.findById(Long
.parseLong((String) event.getRowKey()));
categoryManager.increaseCategoryOrder(subCategory,
parentCategory);
break;
}
case COL_EDIT: {
selectedCategoryId.setSelectedKey(state,
event.getRowKey());
categoriesTab.showCategoryEditForm(state);
break;
}
case COL_DEL: {
final CdiUtil cdiUtil = CdiUtil.createCdiUtil();
final CategoryRepository categoryRepo = cdiUtil
.findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(Long
.parseLong((String) event.getRowKey()));
categoryRepo.delete(category);
break;
}
}
}
@Override
public void headSelected(final TableActionEvent event) {
//Nothing
}
});
setModelBuilder(new SubCategoriesTableModelBuilder());
}
private class SubCategoriesTableModelBuilder
extends LockableImpl
implements TableModelBuilder {
@Override
public TableModel makeModel(final Table table, final PageState state) {
table.getRowSelectionModel().clearSelection(state);
return new SubCategoriesTableModel(state);
}
}
private class SubCategoriesTableModel implements TableModel {
private final List<Category> subCategories;
private int index = -1;
public SubCategoriesTableModel(final PageState state) {
final CategoryRepository categoryRepo = CdiUtil.
createCdiUtil().findBean(CategoryRepository.class);
final Category category = categoryRepo.findById(Long.parseLong(
selectedCategoryId.getSelectedKey(state)));
subCategories = new ArrayList<>(category.getSubCategories());
subCategories.sort((c1, c2) -> {
return Long.compare(c1.getCategoryOrder(),
c2.getCategoryOrder());
});
}
@Override
public int getColumnCount() {
return 5;
}
@Override
public boolean nextRow() {
index++;
return index < subCategories.size();
}
@Override
public Object getElementAt(final int columnIndex) {
final Category subCategory = subCategories.get(index);
switch (columnIndex) {
case COL_NAME:
return subCategory.getName();
case COL_UP:
if (index == 0) {
return null;
} else {
return new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.up",
ADMIN_BUNDLE));
}
case COL_DOWN:
if (index == subCategories.size() - 1) {
return null;
} else {
return new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.down",
ADMIN_BUNDLE));
}
case COL_EDIT:
return new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.edit",
ADMIN_BUNDLE));
case COL_DEL:
if (isDeletable(subCategory)) {
return new Label(new GlobalizedMessage(
"ui.admin.categories.category.subcategories.del",
ADMIN_BUNDLE));
} else {
return null;
}
default:
throw new IllegalArgumentException(
"Not a valid column index");
}
}
private boolean isDeletable(final Category category) {
final List<Category> subCats = category.getSubCategories();
final List<Categorization> objects = category.getObjects();
return (subCats == null || subCats.isEmpty())
&& (objects == null || objects.isEmpty());
}
@Override
public Object getKeyAt(final int columnIndex) {
return subCategories.get(index).getObjectId();
}
}
}

View File

@ -22,6 +22,7 @@ import static org.libreccm.core.CoreConstants.*;
import org.hibernate.validator.constraints.NotBlank;
import org.libreccm.core.CcmObject;
import org.libreccm.core.DefaultEntityGraph;
import org.libreccm.l10n.LocalizedString;
import java.io.Serializable;
@ -37,8 +38,12 @@ import javax.persistence.Entity;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToOne;
import javax.persistence.NamedAttributeNode;
import javax.persistence.NamedEntityGraph;
import javax.persistence.NamedEntityGraphs;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.NamedSubgraph;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.validation.constraints.Pattern;
@ -59,13 +64,34 @@ import javax.validation.constraints.Pattern;
@Entity
@Table(name = "CATEGORIES", schema = DB_SCHEMA)
@NamedQueries({
@NamedQuery(name = "Category.topLevelCategories",
query = "SELECT c FROM Category c WHERE c.parentCategory IS NULL"),
@NamedQuery(name = "Category.topLevelCategories",
query
= "SELECT c FROM Category c WHERE c.parentCategory IS NULL"),
@NamedQuery(name = "Category.findByName",
query = "SELECT c FROM Category c WHERE c.name = :name")
})
@NamedEntityGraphs({
@NamedEntityGraph(
name = "Category.withSubCategoriesAndObjects",
attributeNodes = {
@NamedAttributeNode(value = "subCategories",
subgraph = "subCategories"),
@NamedAttributeNode(value = "objects")
},
subgraphs = {
@NamedSubgraph(
name = "subCategories",
attributeNodes = {
@NamedAttributeNode("subCategories"),
@NamedAttributeNode("objects")
}
)
}
)
})
@DefaultEntityGraph("Category.withSubCategoriesAndObjects")
public class Category extends CcmObject implements Serializable {
private static final long serialVersionUID = -7250208963391878547L;
/**
@ -74,7 +100,7 @@ public class Category extends CcmObject implements Serializable {
*/
@Column(name = "UNIQUE_ID")
private String uniqueId;
/**
* The name of the category. This is used as URL stub, therefore only the
* characters a to z, A to Z and 0 to 9 are allowed.
@ -89,12 +115,12 @@ public class Category extends CcmObject implements Serializable {
*/
@Embedded
@AssociationOverride(
name = "values",
joinTable = @JoinTable(name = "CATEGORY_TITLES",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")}
))
name = "values",
joinTable = @JoinTable(name = "CATEGORY_TITLES",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")}
))
private LocalizedString title;
/**
@ -102,12 +128,12 @@ public class Category extends CcmObject implements Serializable {
*/
@Embedded
@AssociationOverride(
name = "values",
joinTable = @JoinTable(name = "CATEGORY_DESCRIPTIONS",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")}
))
name = "values",
joinTable = @JoinTable(name = "CATEGORY_DESCRIPTIONS",
schema = DB_SCHEMA,
joinColumns = {
@JoinColumn(name = "OBJECT_ID")}
))
private LocalizedString description;
/**
@ -164,7 +190,7 @@ public class Category extends CcmObject implements Serializable {
objects = new ArrayList<>();
subCategories = new ArrayList<>();
enabled = true;
visible= true;
visible = true;
abstractCategory = false;
categoryOrder = 0;
}
@ -316,7 +342,7 @@ public class Category extends CcmObject implements Serializable {
if (!super.equals(obj)) {
return false;
}
if (obj == null) {
return false;
}
@ -363,12 +389,12 @@ public class Category extends CcmObject implements Serializable {
@Override
public String toString(final String data) {
return super.toString(String.format(", uniqueId = %s, "
+ "name = \"%s\", "
+ "title = %s, "
+ "enabled = %b, "
+ "visible = %b, "
+ "abstractCategory = %s, "
+ "categoryOrder = %d%s",
+ "name = \"%s\", "
+ "title = %s, "
+ "enabled = %b, "
+ "visible = %b, "
+ "abstractCategory = %s, "
+ "categoryOrder = %d%s",
uniqueId,
name,
Objects.toString(title),

View File

@ -23,6 +23,7 @@ import org.apache.logging.log4j.Logger;
import org.libreccm.core.CcmObject;
import org.libreccm.core.CcmObjectRepository;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.RequestScoped;
@ -186,11 +187,61 @@ public class CategoryManager {
* object is not assigned to
* the provided category.
*/
@Transactional(Transactional.TxType.REQUIRED)
public void increaseObjectOrder(final CcmObject object,
final Category category)
throws ObjectNotAssignedToCategoryException {
// TODO implement method
throw new UnsupportedOperationException();
if (object == null) {
throw new IllegalArgumentException("The object can't be null.");
}
if (category == null) {
throw new IllegalArgumentException("The category can't be null");
}
final Categorization categorization;
final Categorization nextCategorization;
Categorization current = null;
int index = 0;
final List<Categorization> objects = new ArrayList<>(category
.getObjects());
objects.sort((o1, o2) -> {
return Long.compare(o1.getObjectOrder(), o2.getObjectOrder());
});
while (index < objects.size()) {
current = objects.get(index);
if (current.getCategorizedObject().equals(object)) {
break;
}
index++;
}
categorization = current;
if ((index + 1) < objects.size()) {
nextCategorization = objects.get(index + 1);
} else {
//No next object, returning silently.
return;
}
if (categorization == null) {
//Object is not part of the category.
throw new ObjectNotAssignedToCategoryException(String.format(
"The object %s is not assigned to the category %s (UUID: %s).",
object.getUuid(),
category.getName(),
category.getUuid()));
}
final long order = categorization.getObjectOrder();
final long nextOrder = nextCategorization.getObjectOrder();
categorization.setObjectOrder(nextOrder);
nextCategorization.setObjectOrder(order);
categoryRepo.save(category);
}
/**
@ -207,11 +258,61 @@ public class CategoryManager {
* object is not assigned to
* the provided category.
*/
@Transactional(Transactional.TxType.REQUIRED)
public void decreaseObjectOrder(final CcmObject object,
final Category category)
throws ObjectNotAssignedToCategoryException {
// TODO implement method
throw new UnsupportedOperationException();
if (object == null) {
throw new IllegalArgumentException("The object can't be null.");
}
if (category == null) {
throw new IllegalArgumentException("The category can't be null");
}
final Categorization categorization;
final Categorization prevCategorization;
Categorization current = null;
int index = 0;
final List<Categorization> objects = new ArrayList<>(category
.getObjects());
objects.sort((o1, o2) -> {
return Long.compare(o1.getObjectOrder(), o2.getObjectOrder());
});
while (index < objects.size()) {
current = objects.get(index);
if (current.getCategorizedObject().equals(object)) {
break;
}
index++;
}
categorization = current;
if ((index - 1) >= 0) {
prevCategorization = objects.get(index - 1);
} else {
//No previous object, returning silently.
return;
}
if (categorization == null) {
//Object is not part of the category.
throw new ObjectNotAssignedToCategoryException(String.format(
"The object %s is not assigned to the category %s (UUID: %s).",
object.getUuid(),
category.getName(),
category.getUuid()));
}
final long order = categorization.getObjectOrder();
final long prevOrder = prevCategorization.getObjectOrder();
categorization.setObjectOrder(prevOrder);
prevCategorization.setObjectOrder(order);
categoryRepo.save(category);
}
/**
@ -229,14 +330,13 @@ public class CategoryManager {
* assigned to the provided
* category.
*/
public void swapObjects(final CcmObject objectA,
final CcmObject objectB,
final Category category)
throws ObjectNotAssignedToCategoryException {
// TODO implement method
throw new UnsupportedOperationException();
}
// public void swapObjects(final CcmObject objectA,
// final CcmObject objectB,
// final Category category)
// throws ObjectNotAssignedToCategoryException {
// // TODO implement method
// throw new UnsupportedOperationException();
// }
/**
* Adds a category as an subcategory to another category. If the category is
* assigned to another category that association is removed.
@ -246,20 +346,25 @@ public class CategoryManager {
* @param parentCategory The category to which the category is added as
* subcategory. Can't be {@code null}.
*/
@Transactional(Transactional.TxType.REQUIRED)
public void addSubCategoryToCategory(final Category subCategory,
final Category parentCategory) {
if (subCategory.getParentCategory() != null) {
final Category oldParent = subCategory.getParentCategory();
removeSubCategoryFromCategory(subCategory, oldParent);
final Category sub = categoryRepo.findById(subCategory.getObjectId());
final Category parent = categoryRepo.findById(parentCategory
.getObjectId());
if (sub.getParentCategory() != null) {
final Category oldParent = sub.getParentCategory();
removeSubCategoryFromCategory(sub, oldParent);
}
final int order = parentCategory.getCategories().size() + 1;
parentCategory.addSubCategory(subCategory);
subCategory.setParentCategory(parentCategory);
subCategory.setCategoryOrder(order);
final int order = parent.getSubCategories().size() + 1;
parent.addSubCategory(sub);
sub.setParentCategory(parent);
sub.setCategoryOrder(order);
categoryRepo.save(parentCategory);
categoryRepo.save(subCategory);
categoryRepo.save(parent);
categoryRepo.save(sub);
}
/**
@ -275,6 +380,7 @@ public class CategoryManager {
* assigned to the provided parent
* category.
*/
@Transactional(Transactional.TxType.REQUIRED)
public void removeSubCategoryFromCategory(final Category subCategory,
final Category parentCategory) {
@ -314,10 +420,59 @@ public class CategoryManager {
* subcategory of the provided parent
* category.
*/
@Transactional(Transactional.TxType.REQUIRED)
public void increaseCategoryOrder(final Category subCategory,
final Category parentCategory) {
// TODO implement method
throw new UnsupportedOperationException();
if (parentCategory == null) {
throw new IllegalArgumentException("parentCategory can't be null.");
}
if (subCategory == null) {
throw new IllegalArgumentException("subCategory can't be null.");
}
boolean found = false;
int index = 0;
final List<Category> subCategories = new ArrayList<>(parentCategory
.getSubCategories());
subCategories.sort((c1, c2) -> {
return Long.compare(c1.getCategoryOrder(), c2.getCategoryOrder());
});
while (index < subCategories.size()) {
if (subCategories.get(index).equals(subCategory)) {
found = true;
break;
}
index++;
}
if (!found) {
throw new IllegalArgumentException(String.format(
"The category %s (UUID: %s) is not a subcategory of the "
+ "category %s (UUID: %s)",
subCategory.getName(),
subCategory.getUuid(),
parentCategory.getName(),
parentCategory.getUuid()));
}
final Category nextCategory;
if ((index + 1) < subCategories.size()) {
nextCategory = subCategories.get(index + 1);
} else {
//No next category, returning sliently.
return;
}
final long order = subCategory.getCategoryOrder();
final long nextOrder = nextCategory.getCategoryOrder();
subCategory.setCategoryOrder(nextOrder);
nextCategory.setCategoryOrder(order);
categoryRepo.save(subCategory);
categoryRepo.save(nextCategory);
}
/**
@ -337,8 +492,56 @@ public class CategoryManager {
*/
public void decreaseCategoryOrder(final Category subCategory,
final Category parentCategory) {
// TODO implement method
throw new UnsupportedOperationException();
if (parentCategory == null) {
throw new IllegalArgumentException("parentCategory can't be null.");
}
if (subCategory == null) {
throw new IllegalArgumentException("subCategory can't be null.");
}
boolean found = false;
int index = 0;
final List<Category> subCategories = new ArrayList<>(parentCategory
.getSubCategories());
subCategories.sort((c1, c2) -> {
return Long.compare(c1.getCategoryOrder(), c2.getCategoryOrder());
});
while (index < subCategories.size()) {
if (subCategories.get(index).equals(subCategory)) {
found = true;
break;
}
index++;
}
if (!found) {
throw new IllegalArgumentException(String.format(
"The category %s (UUID: %s) is not a subcategory of the "
+ "category %s (UUID: %s)",
subCategory.getName(),
subCategory.getUuid(),
parentCategory.getName(),
parentCategory.getUuid()));
}
final Category prevCategory;
if ((index - 1) >= 0) {
prevCategory = subCategories.get(index - 1);
} else {
//No previous object, returning silently
return;
}
final long order = subCategory.getCategoryOrder();
final long prevOrder = prevCategory.getCategoryOrder();
subCategory.setCategoryOrder(prevOrder);
prevCategory.setCategoryOrder(order);
categoryRepo.save(subCategory);
categoryRepo.save(prevCategory);
}
/**
@ -353,11 +556,10 @@ public class CategoryManager {
* subcategories of the provided parent
* category.qq
*/
public void swapCategories(final Category subCategoryA,
final Category subCategoryB,
final Category parentCategory) {
// TODO implement method
throw new UnsupportedOperationException();
}
// public void swapCategories(final Category subCategoryA,
// final Category subCategoryB,
// final Category parentCategory) {
// // TODO implement method
// throw new UnsupportedOperationException();
// }
}

View File

@ -57,7 +57,7 @@ public class CategoryRepository extends AbstractEntityRepository<Long, Category>
public void initNewEntity(final Category category) {
category.setUuid(UUID.randomUUID().toString());
}
/**
* Retrieves a list of all top level categories (Categories without a parent
* category).
@ -151,17 +151,4 @@ public class CategoryRepository extends AbstractEntityRepository<Long, Category>
return current;
}
/**
* Retrieves all categories which are not assigned to another category as
* subcategory or the an {@link Domain} as root category.
*
* @return A list of all orphaned categories. Normally this list should be
* empty.
*/
public List<Category> getOrphanedCategories() {
// TODO implement method
throw new UnsupportedOperationException();
}
}

View File

@ -98,7 +98,10 @@ import javax.xml.bind.annotation.XmlRootElement;
name = "subCategories",
attributeNodes = {
@NamedAttributeNode("subCategories")
})}),
}
)
}
),
@NamedEntityGraph(
name = "Domain.withOwners",
attributeNodes = {

View File

@ -459,3 +459,69 @@ ui.admin.configuration.setting.localized_string.col_lang=Language
ui.admin.configuration.setting.localized_string.col_value=Value
ui.admin.configuration.setting.localized_string.col_del=Delete
ui.admin.configuration.setting.localized_string.col_edit=Edit
ui.admin.categories.category.create_new_subcategory=Create new sub category below category {0}
ui.admin.categories.category.name.label=Name
ui.admin.categories.category.name.errors.not_blank=The name of a category can't be blank.
ui.admin.categories.category.description.edit.back=Back to category properties
ui.admin.categories.category.description.edit_for_lang=Edit description of category {0} for locale {1}
ui.admin.categories.category.description.add_for_lang=Add description for category {0} for locale {1}
ui.admin.categories.category.description.label=Description
ui.admin.categories.category.description.error.not_blank=The description of a category can't be blank.
ui.admin.categories.category_details.description.none=No descriptions
ui.admin.categories.category_details.description.col_lang=Language
ui.admin.categories.category_details.description.col_value=Description
ui.admin.categories.category_details.description.col_edit=Edit
ui.admin.categories.category_details.description.col_del=Delete
ui.admin.categories.category_details.description.del_confirm=Are you sure do delete this description?
ui.admin.categories.category_details.description.edit=Edit
ui.admin.categories.category_details.description.del=Delete
ui.admin.categories.category_details.back=Back
ui.admin.categories.category_details.basic_properties.edit=Edit basic properties
ui.admin.categories.category_details.basic_properties=Basic properties
ui.admin.categories.category_details.category_title=Title of the category
ui.admin.categories.category_details.description=Description of the category
ui.admin.categories.category_details.category_title.add.label=Add title
ui.admin.categories.category_details.category_title.add.submit=Add
ui.admin.categories.category_details.category_desc.add.label=Add description
ui.admin.categories.category_details.category_desc.add.submit=Add
ui.admin.categories.category.edit_category=Edit category {0}
ui.admin.categories.category.property_sheet.name=Name
ui.admin.categories.category.title.edit.back=Back
ui.admin.categories.category.title.edit_for_lang=Edit title of category {0} for locale {1}
ui.admin.categories.category.title.add_for_lang=Add title for locale {1} to category {0}
ui.admin.categories.category.title.label=Title
ui.admin.categories.category.title.error.not_blank=The title of category can't be blank.
ui.admin.categories.category_details.title.none=No titles
ui.admin.categories.category_details.title.col_lang=Language
ui.admin.categories.category_details.title.col_value=Title
ui.admin.categories.category_details.title.col_edit=Edit
ui.admin.categories.category_details.title.col_del=Delete
ui.admin.categories.category_details.title.del_confirm=Are you sure to delete this title?
ui.admin.categories.category_details.title.edit=Edit
ui.admin.categories.category_details.title.del=Delete
ui.admin.categories.domain_details.description.col_edit=Edit
ui.admin.categories.domain_details.description.edit=Edit
ui.admin.categories.domain_details.title.col_edit=Edit
ui.admin.categories.category.no_subcategories=This category has no subcategories
ui.admin.categories.category.subcategories.col_name=Name
ui.admin.categories.category.subcategories.col_up=\u25b2 Up
ui.admin.categories.category.subcategories.col_down=\u25bc Down
ui.admin.categories.category.subcategories.col_edit=Edit
ui.admin.categories.category.subcategories.del_confirm=Are you sure to delete this category?
ui.admin.categories.category.subcategories.up=\u25b2 Up
ui.admin.categories.category.subcategories.down=\u25bc Down
ui.admin.categories.category.subcategories.edit=Edit
ui.admin.categories.category.subcategories.del=Delete
ui.admin.categories.category.move.heading=Move category {0}
ui.admin.categories.domain.details.heading=Details for domain {0}
ui.admin.categories.category_details.heading=Details for category {0}
ui.admin.categories.category_details.subcategories.add=Add subcategory
ui.admin.categories.category_details.subcategories.header=Subcategories
ui.admin.categories.category.subcategories.col_del=Delete
ui.admin.categories.category_details.move_category=Move category
ui.admin.categories.category.property_sheet.visible=Visible?
ui.admin.categories.category.property_sheet.enabled=Enabled?
ui.admin.categories.category.property_sheet.abstract=Abstract?
ui.admin.categories.category.name.enabled=Enabled?
ui.admin.categories.category.name.visible=Visible?
ui.admin.categories.category.name.abstract=Abstract?

View File

@ -364,7 +364,7 @@ ui.admin.categories.domain_form.fields.released=Freigegeben
ui.admin.categories.domain_form.errors.domain_key_blank=Der Key einer Domain darf nicht leer sein.
ui.admin.categories.domain_form.errors.version_blank=Die Version einer Domain darf nicht leer sein.
ui.admin.categories.domain_form.fields.root_category_name=Name der Wurzelkategorie
ui.admin.categories.domain_details.back=Zur\u00fcck zur List der Domains
ui.admin.categories.domain_details.back=Zur\u00fcck zur Liste der Domains
ui.admin.categories.domain_details.basic_properties.edit=Basiseigenschaften bearbeiten
ui.admin.categories.domain_details.basic_properties=Basiseigenschaften
ui.admin.categories.domain_details.domain_title=Lokalisierter Titel der Domain
@ -410,7 +410,7 @@ ui.admin.categories.domain_details.mappings.create=hinzuf\u00fcgen
ui.admin.categories.doamin_details.mappings.error.please_select_app=Bitte w\u00e4hlen Sie eine Applikation aus.
ui.admin.categories.domain_details.mappings.remove.confirm=Sind Sie sicher, dass Sie dieses Mapping entfernen wollen?
ui.admin.categories.tree.header=Kategorien
ui.admin.categories.tree.back=Zur\u00fcck zur Domain Eigenschaften
ui.admin.categories.tree.back=Zur\u00fcck zur den Eigenschaften der Domain
ui.admin.configuration.classes.filter.heading=Konfigurationen filtern
ui.admin.configuration.classes.filter.submit=Anwenden
ui.admin.configuration.classes.filter.clear=Zur\u00fccksetzen
@ -462,3 +462,69 @@ ui.admin.configuration.setting.localized_string.col_lang=Sprache
ui.admin.configuration.setting.localized_string.col_value=Wert
ui.admin.configuration.setting.localized_string.col_del=L\u00f6schen
ui.admin.configuration.setting.localized_string.col_edit=Bearbeiten
ui.admin.categories.category.create_new_subcategory=Neue Unterkategorie f\u00fcr Kategorie {0} erstellen
ui.admin.categories.category.name.label=Name
ui.admin.categories.category.name.errors.not_blank=Der Name einer Kategorie darf nicht leer sein.
ui.admin.categories.category.description.edit.back=Zur\u00fcck zu den Eigenschaften der Kategorie
ui.admin.categories.category.description.edit_for_lang=Beschreibung der Kategorie {0} f\u00fcr {1} bearbeiten
ui.admin.categories.category.description.add_for_lang=Beschreibung f\u00fcr {1} zur Kategorie {0} hinzuf\u00fcgen
ui.admin.categories.category.description.label=Beschreibung
ui.admin.categories.category.description.error.not_blank=Die Beschreibung einer Kategorie darf nicht leer sein.
ui.admin.categories.category_details.description.none=Keine Beschreibungen
ui.admin.categories.category_details.description.col_lang=Sprache
ui.admin.categories.category_details.description.col_value=Beschreibung
ui.admin.categories.category_details.description.col_edit=Bearbeiten
ui.admin.categories.category_details.description.col_del=L\u00f6schen
ui.admin.categories.category_details.description.del_confirm=Sind Sie sicher, dass Sie diese Beschreibung l\u00f6schen wollen?
ui.admin.categories.category_details.description.edit=Bearbeiten
ui.admin.categories.category_details.description.del=L\u00f6schen
ui.admin.categories.category_details.back=Zur\u00fcck
ui.admin.categories.category_details.basic_properties.edit=Basiseigenschaften bearbeiten
ui.admin.categories.category_details.basic_properties=Basiseigenschaften
ui.admin.categories.category_details.category_title=Titel der Kategorie
ui.admin.categories.category_details.description=Beschreibung der Kategorie
ui.admin.categories.category_details.category_title.add.label=Titel hinzuf\u00fcgen
ui.admin.categories.category_details.category_title.add.submit=Hinzuf\u00fcgen
ui.admin.categories.category_details.category_desc.add.label=Beschreibung hinzuf\u00fcgen
ui.admin.categories.category_details.category_desc.add.submit=Hinzuf\u00fcgen
ui.admin.categories.category.edit_category=Kategorie {0} bearbeiten
ui.admin.categories.category.property_sheet.name=Name
ui.admin.categories.category.title.edit.back=Zur\u00fcck
ui.admin.categories.category.title.edit_for_lang=Titel der Kategorie {0} f\u00fcr Sprache {1} bearbeiten
ui.admin.categories.category.title.add_for_lang=Titel f\u00fcr Sprache {1} zur Kategorie {0} hinzuf\u00fcgen
ui.admin.categories.category.title.label=Titel
ui.admin.categories.category.title.error.not_blank=Der Titel einer Kategorie darf nicht leer sein.
ui.admin.categories.category_details.title.none=Keine Titel
ui.admin.categories.category_details.title.col_lang=Sprache
ui.admin.categories.category_details.title.col_value=Titel
ui.admin.categories.category_details.title.col_edit=Bearbeiten
ui.admin.categories.category_details.title.col_del=L\u00f6schen
ui.admin.categories.category_details.title.del_confirm=Sind Sie sicher, dass Sie diesen Titel l\u00f6schen wollen?
ui.admin.categories.category_details.title.edit=Bearbeiten
ui.admin.categories.category_details.title.del=L\u00f6schen
ui.admin.categories.domain_details.description.col_edit=Bearbeiten
ui.admin.categories.domain_details.description.edit=Bearbeiten
ui.admin.categories.domain_details.title.col_edit=Bearbeiten
ui.admin.categories.category.no_subcategories=Diese Kategorie hat keine Unterkategorien
ui.admin.categories.category.subcategories.col_name=Name
ui.admin.categories.category.subcategories.col_up=\u25b2 Hoch
ui.admin.categories.category.subcategories.col_down=\u25bc Runter
ui.admin.categories.category.subcategories.col_edit=Bearbeiten
ui.admin.categories.category.subcategories.del_confirm=Sind Sie sicher, dass Sie diese Kategorie l\u00f6schen wollen?
ui.admin.categories.category.subcategories.up=\u25b2 Hoch
ui.admin.categories.category.subcategories.down=\u25bc Runter
ui.admin.categories.category.subcategories.edit=Bearbeiten
ui.admin.categories.category.subcategories.del=L\u00f6schen
ui.admin.categories.category.move.heading=Kategorie {0} verschieben
ui.admin.categories.domain.details.heading=Eigenschaften der Domain {0}
ui.admin.categories.category_details.heading=Eigenschaften der Kategorie {0}
ui.admin.categories.category_details.subcategories.add=Unterkategorie hinzuf\u00fcgen
ui.admin.categories.category_details.subcategories.header=Unterkategorien
ui.admin.categories.category.subcategories.col_del=L\u00f6schen
ui.admin.categories.category_details.move_category=Kategorie verschieben
ui.admin.categories.category.property_sheet.visible=Sichtbar?
ui.admin.categories.category.property_sheet.enabled=Aktiviert?
ui.admin.categories.category.property_sheet.abstract=Abstrakt?
ui.admin.categories.category.name.enabled=Aktiviert?
ui.admin.categories.category.name.visible=Sichtbar?
ui.admin.categories.category.name.abstract=Abstrakt?

View File

@ -435,3 +435,89 @@ ui.admin.configuration.setting.localized_string.col_lang=Language
ui.admin.configuration.setting.localized_string.col_value=Value
ui.admin.configuration.setting.localized_string.col_del=Delete
ui.admin.configuration.setting.localized_string.col_edit=Edit
ui.admin.categories.category.create_new_subcategory=Create new sub category below category {0}
ui.admin.categories.category.name.label=Name
ui.admin.categories.category.name.errors.not_blank=The name of a category can't be blank.
ui.admin.categories.category.description.edit.back=Back to category properties
ui.admin.categories.category.description.edit_for_lang=Edit description of category {0} for locale {1}
ui.admin.categories.category.description.add_for_lang=Add description for category {0} for locale {1}
ui.admin.categories.category.description.label=Description
ui.admin.categories.category.description.error.not_blank=The description of a category can't be blank.
ui.admin.categories.category_details.description.none=No descriptions
ui.admin.categories.category_details.description.col_lang=Language
ui.admin.categories.category_details.description.col_value=Description
ui.admin.categories.category_details.description.col_edit=Edit
ui.admin.categories.category_details.description.col_del=Delete
ui.admin.categories.category_details.description.del_confirm=Are you sure do delete this description?
ui.admin.categories.category_details.description.edit=Edit
ui.admin.categories.category_details.description.del=Delete
ui.admin.categories.category_details.back=Back
ui.admin.categories.category_details.basic_properties.edit=Edit basic properties
ui.admin.categories.category_details.basic_properties=Basic properties
ui.admin.categories.category_details.category_title=Title of the category
ui.admin.categories.category_details.description=Description of the category
ui.admin.categories.category_details.category_title.add.label=Add title
ui.admin.categories.category_details.category_title.add.submit=Add
ui.admin.categories.category_details.category_desc.add.label=Add description
ui.admin.categories.category_details.category_desc.add.submit=Add
ui.admin.categories.category.edit_category=Edit category {0}
ui.admin.categories.category.property_sheet.name=Name
ui.admin.categories.category.title.edit.back=Back
ui.admin.categories.category.title.edit_for_lang=Edit title of category {0} for locale {1}
ui.admin.categories.category.title.add_for_lang=Add title for locale {1} to category {0}
ui.admin.categories.category.title.label=Title
ui.admin.categories.category.title.error.not_blank=The title of category can't be blank.
ui.admin.categories.category_details.title.none=No titles
ui.admin.categories.category_details.title.col_lang=Language
ui.admin.categories.category_details.title.col_value=Title
ui.admin.categories.category_details.title.col_edit=Edit
ui.admin.categories.category_details.title.col_del=Delete
ui.admin.categories.category_details.title.del_confirm=Are you sure to delete this title?
ui.admin.categories.category_details.title.edit=Edit
ui.admin.categories.category_details.title.del=Delete
ui.admin.categories.domain_details.description.col_edit=Edit
ui.admin.categories.domain_details.description.edit=Edit
ui.admin.categories.domain_details.title.col_edit=Edit
ui.admin.categories.category.no_subcategories=This category has no subcategories
ui.admin.categories.category.subcategories.col_name=Name
ui.admin.categories.category.subcategories.col_up=\u25b2 Up
ui.admin.categories.category.subcategories.col_down=\u25bc Down
ui.admin.categories.category.subcategories.col_edit=Edit
ui.admin.categories.category.subcategories.del_confirm=Are you sure to delete this category?
ui.admin.categories.category.subcategories.up=\u25b2 Up
ui.admin.categories.category.subcategories.down=\u25bc Down
ui.admin.categories.category.subcategories.edit=Edit
ui.admin.categories.category.subcategories.del=Delete
ui.admin.categories.category.move.heading=Move category {0}
ui.admin.categories.domain.details.heading=Details for domain {0}
ui.admin.categories.category_details.heading=Details for category {0}
ui.admin.categories.category_details.subcategories.add=Add subcategory
ui.admin.categories.category_details.subcategories.header=Subcategories
ui.admin.categories.category.subcategories.col_del=Delete
ui.admin.categories.category_details.move_category=Move category
ui.admin.categories.category.property_sheet.visible=Visible?
ui.admin.categories.category.property_sheet.enabled=Enabled?
ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header=Description
ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header=Title
ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header=Path
ui.admin.applications.placeholder=There is no administration panel for instances of this application type yet.
ui.admin.applications.parent.label=Select parent application
ui.admin.applications.no_settings=This application has no settings (yet).
ui.admin.applications.form_not_compatible_now=This application administration form is not yet compatible with this application pane. Please use the applications own administration form.
ui.admin.applications.ApplicationInstancePane.path.label=Path of the application
ui.admin.applications.ApplicationInfoSection.desc.label=Description
ui.admin.applications.ApplicationInfoSection.app_class.label=Application Class
ui.admin.applications.ApplicationInfoSection.heading=Application information
ui.admin.applications.ApplicationInfoSection.singleton.label=Singleton
ui.admin.applications.ApplicationInfoSection.singleton.no=No
ui.admin.applications.ApplicationInfoSection.singleton.yes=Yes
ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found=No instance found
ui.admin.applications.ApplicationInfoSection.title.label=Title
ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label=Path of the singleton instance
ui.admin.applications.ApplicationInstancePane.desc.label=Description
ui.admin.applications.ApplicationInstancePane.info.heading=Instance data
ui.admin.applications.ApplicationInstancePane.manage.heading=Instance specific settings
ui.admin.categories.category.property_sheet.abstract=Abstract?
ui.admin.categories.category.name.enabled=Enabled?
ui.admin.categories.category.name.visible=Visible?
ui.admin.categories.category.name.abstract=Abstract?

View File

@ -77,7 +77,7 @@ ui.admin.user.userpasswordform.passwordlabel=Mot de passe:
ui.admin.user.userpasswordform.question=Question:
ui.admin.user.userpasswordform.submit=Changer
ui.admin.tab.applications=Applications
ui.admin.applications.tree.heading=
ui.admin.applications.tree.heading=Applications
ui.admin.applications.url.validation.not_blank=The URL of an application instance can is mandatory.
ui.admin.applications.url.valiation.minmaxlength=The length of an URL of an application instance must be between 1 and 100 characters.
ui.admin.applications.title.validation.not_blank=Title is mandatory for an application instance.
@ -426,3 +426,89 @@ ui.admin.configuration.setting.localized_string.col_lang=Language
ui.admin.configuration.setting.localized_string.col_value=Value
ui.admin.configuration.setting.localized_string.col_del=Delete
ui.admin.configuration.setting.localized_string.col_edit=Edit
ui.admin.categories.category.create_new_subcategory=Create new sub category below category {0}
ui.admin.categories.category.name.label=Name
ui.admin.categories.category.name.errors.not_blank=The name of a category can't be blank.
ui.admin.categories.category.description.edit.back=Back to category properties
ui.admin.categories.category.description.edit_for_lang=Edit description of category {0} for locale {1}
ui.admin.categories.category.description.add_for_lang=Add description for category {0} for locale {1}
ui.admin.categories.category.description.label=Description
ui.admin.categories.category.description.error.not_blank=The description of a category can't be blank.
ui.admin.categories.category_details.description.none=No descriptions
ui.admin.categories.category_details.description.col_lang=Language
ui.admin.categories.category_details.description.col_value=Description
ui.admin.categories.category_details.description.col_edit=Edit
ui.admin.categories.category_details.description.col_del=Delete
ui.admin.categories.category_details.description.del_confirm=Are you sure do delete this description?
ui.admin.categories.category_details.description.edit=Edit
ui.admin.categories.category_details.description.del=Delete
ui.admin.categories.category_details.back=Back
ui.admin.categories.category_details.basic_properties.edit=Edit basic properties
ui.admin.categories.category_details.basic_properties=Basic properties
ui.admin.categories.category_details.category_title=Title of the category
ui.admin.categories.category_details.description=Description of the category
ui.admin.categories.category_details.category_title.add.label=Add title
ui.admin.categories.category_details.category_title.add.submit=Add
ui.admin.categories.category_details.category_desc.add.label=Add description
ui.admin.categories.category_details.category_desc.add.submit=Add
ui.admin.categories.category.edit_category=Edit category {0}
ui.admin.categories.category.property_sheet.name=Name
ui.admin.categories.category.title.edit.back=Back
ui.admin.categories.category.title.edit_for_lang=Edit title of category {0} for locale {1}
ui.admin.categories.category.title.add_for_lang=Add title for locale {1} to category {0}
ui.admin.categories.category.title.label=Title
ui.admin.categories.category.title.error.not_blank=The title of category can't be blank.
ui.admin.categories.category_details.title.none=No titles
ui.admin.categories.category_details.title.col_lang=Language
ui.admin.categories.category_details.title.col_value=Title
ui.admin.categories.category_details.title.col_edit=Edit
ui.admin.categories.category_details.title.col_del=Delete
ui.admin.categories.category_details.title.del_confirm=Are you sure to delete this title?
ui.admin.categories.category_details.title.edit=Edit
ui.admin.categories.category_details.title.del=Delete
ui.admin.categories.domain_details.description.col_edit=Edit
ui.admin.categories.domain_details.description.edit=Edit
ui.admin.categories.domain_details.title.col_edit=Edit
ui.admin.categories.category.no_subcategories=This category has no subcategories
ui.admin.categories.category.subcategories.col_name=Name
ui.admin.categories.category.subcategories.col_up=\u25b2 Up
ui.admin.categories.category.subcategories.col_down=\u25bc Down
ui.admin.categories.category.subcategories.col_edit=Edit
ui.admin.categories.category.subcategories.del_confirm=Are you sure to delete this category?
ui.admin.categories.category.subcategories.up=\u25b2 Up
ui.admin.categories.category.subcategories.down=\u25bc Down
ui.admin.categories.category.subcategories.edit=Edit
ui.admin.categories.category.subcategories.del=Delete
ui.admin.categories.category.move.heading=Move category {0}
ui.admin.categories.domain.details.heading=Details for domain {0}
ui.admin.categories.category_details.heading=Details for category {0}
ui.admin.categories.category_details.subcategories.add=Add subcategory
ui.admin.categories.category_details.subcategories.header=Subcategories
ui.admin.categories.category.subcategories.col_del=Delete
ui.admin.categories.category_details.move_category=Move category
ui.admin.categories.category.property_sheet.visible=Visible?
ui.admin.categories.category.property_sheet.enabled=Enabled?
ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_desc.header=Description
ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_title.header=Title
ui.admin.applicationsMultiInstanceApplicationPane.instances.table.col_url.header=Path
ui.admin.applications.placeholder=There is no administration panel for instances of this application type yet.
ui.admin.applications.parent.label=Select parent application
ui.admin.applications.no_settings=This application has no settings (yet).
ui.admin.applications.form_not_compatible_now=This application administration form is not yet compatible with this application pane. Please use the applications own administration form.
ui.admin.applications.ApplicationInstancePane.path.label=Path of the application
ui.admin.applications.ApplicationInfoSection.desc.label=Description
ui.admin.applications.ApplicationInfoSection.app_class.label=Application Class
ui.admin.applications.ApplicationInfoSection.heading=Application information
ui.admin.applications.ApplicationInfoSection.singleton.label=Singleton
ui.admin.applications.ApplicationInfoSection.singleton.no=No
ui.admin.applications.ApplicationInfoSection.singleton.yes=Yes
ui.admin.applications.ApplicationInfoSection.singleton_instance.no_instance_found=No instance found
ui.admin.applications.ApplicationInfoSection.title.label=Title
ui.admin.applications.ApplicationInfoSection.singleton_instance.path.label=Path of the singleton instance
ui.admin.applications.ApplicationInstancePane.desc.label=Description
ui.admin.applications.ApplicationInstancePane.info.heading=Instance data
ui.admin.applications.ApplicationInstancePane.manage.heading=Instance specific settings
ui.admin.categories.category.property_sheet.abstract=Abstract?
ui.admin.categories.category.name.enabled=Enabled?
ui.admin.categories.category.name.visible=Visible?
ui.admin.categories.category.name.abstract=Abstract?