Finishing UI for category management
parent
a202973bc6
commit
6e7b6b8dd8
|
|
@ -23,6 +23,8 @@ import org.libreccm.api.IdentifierParser;
|
||||||
import org.libreccm.categorization.Category;
|
import org.libreccm.categorization.Category;
|
||||||
import org.libreccm.categorization.CategoryManager;
|
import org.libreccm.categorization.CategoryManager;
|
||||||
import org.libreccm.categorization.CategoryRepository;
|
import org.libreccm.categorization.CategoryRepository;
|
||||||
|
import org.libreccm.categorization.Domain;
|
||||||
|
import org.libreccm.categorization.DomainRepository;
|
||||||
import org.libreccm.core.CoreConstants;
|
import org.libreccm.core.CoreConstants;
|
||||||
import org.libreccm.security.AuthorizationRequired;
|
import org.libreccm.security.AuthorizationRequired;
|
||||||
import org.libreccm.security.RequiresPrivilege;
|
import org.libreccm.security.RequiresPrivilege;
|
||||||
|
|
@ -30,8 +32,6 @@ import org.libreccm.ui.Message;
|
||||||
import org.libreccm.ui.MessageType;
|
import org.libreccm.ui.MessageType;
|
||||||
import org.libreccm.ui.admin.AdminMessages;
|
import org.libreccm.ui.admin.AdminMessages;
|
||||||
|
|
||||||
import java.net.URLDecoder;
|
|
||||||
import java.nio.charset.StandardCharsets;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
@ -40,16 +40,13 @@ import javax.enterprise.context.RequestScoped;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
import javax.mvc.Controller;
|
import javax.mvc.Controller;
|
||||||
import javax.mvc.Models;
|
import javax.mvc.Models;
|
||||||
import javax.servlet.http.HttpServletRequest;
|
|
||||||
import javax.transaction.Transactional;
|
import javax.transaction.Transactional;
|
||||||
import javax.ws.rs.Consumes;
|
import javax.ws.rs.Consumes;
|
||||||
import javax.ws.rs.Encoded;
|
|
||||||
import javax.ws.rs.FormParam;
|
import javax.ws.rs.FormParam;
|
||||||
import javax.ws.rs.GET;
|
import javax.ws.rs.GET;
|
||||||
import javax.ws.rs.POST;
|
import javax.ws.rs.POST;
|
||||||
import javax.ws.rs.Path;
|
import javax.ws.rs.Path;
|
||||||
import javax.ws.rs.PathParam;
|
import javax.ws.rs.PathParam;
|
||||||
import javax.ws.rs.core.Context;
|
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -73,6 +70,9 @@ public class CategoriesController {
|
||||||
@Inject
|
@Inject
|
||||||
private CategoryRepository categoryRepository;
|
private CategoryRepository categoryRepository;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private DomainRepository domainRepository;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private IdentifierParser identifierParser;
|
private IdentifierParser identifierParser;
|
||||||
|
|
||||||
|
|
@ -635,4 +635,116 @@ public class CategoriesController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@POST
|
||||||
|
@Path("/{categoryIdentifier}/subcategories/{subCategoryIdentifier}/reorder")
|
||||||
|
@AuthorizationRequired
|
||||||
|
@RequiresPrivilege(CoreConstants.PRIVILEGE_ADMIN)
|
||||||
|
@Transactional(Transactional.TxType.REQUIRED)
|
||||||
|
public String reorderSubCategory(
|
||||||
|
@PathParam("categoryIdentifier") final String categoryIdentifierParam,
|
||||||
|
@PathParam("subCategoryIdentifier") final String subCategoryIdentifierParam,
|
||||||
|
@FormParam("direction") final String direction
|
||||||
|
) {
|
||||||
|
final Identifier categoryIdentifier = identifierParser.parseIdentifier(
|
||||||
|
categoryIdentifierParam
|
||||||
|
);
|
||||||
|
final Identifier subCategoryIdentifier = identifierParser
|
||||||
|
.parseIdentifier(subCategoryIdentifierParam);
|
||||||
|
|
||||||
|
final Optional<Category> categoryResult;
|
||||||
|
switch (categoryIdentifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
categoryResult = categoryRepository.findById(
|
||||||
|
Long.parseLong(categoryIdentifier.getIdentifier())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
categoryResult = categoryRepository.findByUuid(
|
||||||
|
categoryIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
final Category category;
|
||||||
|
if (categoryResult.isPresent()) {
|
||||||
|
category = categoryResult.get();
|
||||||
|
} else {
|
||||||
|
categoryDetailsModel.addMessage(
|
||||||
|
new Message(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"categories.not_found.message",
|
||||||
|
Arrays.asList(categoryIdentifierParam)
|
||||||
|
), MessageType.WARNING
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return "org/libreccm/ui/admin/categories/category-not-found.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
final Optional<Category> subCategoryResult;
|
||||||
|
switch (subCategoryIdentifier.getType()) {
|
||||||
|
case ID:
|
||||||
|
subCategoryResult = categoryRepository.findById(
|
||||||
|
Long.parseLong(subCategoryIdentifier.getIdentifier())
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
subCategoryResult = categoryRepository.findByUuid(
|
||||||
|
subCategoryIdentifier.getIdentifier()
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
final Category subCategory;
|
||||||
|
if (subCategoryResult.isPresent()) {
|
||||||
|
subCategory = subCategoryResult.get();
|
||||||
|
} else {
|
||||||
|
categoryDetailsModel.addMessage(
|
||||||
|
new Message(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"categories.not_found.message",
|
||||||
|
Arrays.asList(subCategoryIdentifierParam)
|
||||||
|
), MessageType.WARNING
|
||||||
|
)
|
||||||
|
);
|
||||||
|
return "org/libreccm/ui/admin/categories/category-not-found.xhtml";
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (direction) {
|
||||||
|
case "DECREASE":
|
||||||
|
categoryManager.decreaseCategoryOrder(subCategory, category);
|
||||||
|
break;
|
||||||
|
case "INCREASE":
|
||||||
|
categoryManager.increaseCategoryOrder(subCategory, category);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
categoryDetailsModel.addMessage(
|
||||||
|
new Message(
|
||||||
|
adminMessages.getMessage(
|
||||||
|
"categories.invalid_direction.message",
|
||||||
|
Arrays.asList(direction)),
|
||||||
|
MessageType.WARNING
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (category.getParentCategory() == null) {
|
||||||
|
final Optional<Domain> categorySystem = domainRepository
|
||||||
|
.findByRootCategory(category);
|
||||||
|
if (categorySystem.isPresent()) {
|
||||||
|
return String.format(
|
||||||
|
"redirect:categorymanager/categorysystems/ID-%d/details",
|
||||||
|
categorySystem.get().getObjectId()
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return String.format(
|
||||||
|
"redirect:categorymanager/categories/ID-%d",
|
||||||
|
category.getObjectId()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return String.format(
|
||||||
|
"redirect:categorymanager/categories/ID-%d",
|
||||||
|
category.getObjectId()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,13 +135,13 @@ public class CategoryFormController {
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return String.format(
|
return String.format(
|
||||||
"redirect:categorymanager/categories/ID-%d/details",
|
"redirect:categorymanager/categories/ID-%d",
|
||||||
parentCategory.getObjectId()
|
parentCategory.getObjectId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return String.format(
|
return String.format(
|
||||||
"redirect:categorymanager/categories/ID-%d/details",
|
"redirect:categorymanager/categories/ID-%d",
|
||||||
parentCategory.getObjectId()
|
parentCategory.getObjectId()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -197,7 +197,7 @@ public class CategoryFormController {
|
||||||
categoryRepository.save(category);
|
categoryRepository.save(category);
|
||||||
|
|
||||||
return String.format(
|
return String.format(
|
||||||
"redirect:categorymanager/categories/ID-%s",
|
"redirect:categorymanager/categories/ID-%d",
|
||||||
category.getObjectId()
|
category.getObjectId()
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -208,6 +208,9 @@
|
||||||
<th>
|
<th>
|
||||||
#{AdminMessages['categories.details.subcategories.table.headings.abstract']}
|
#{AdminMessages['categories.details.subcategories.table.headings.abstract']}
|
||||||
</th>
|
</th>
|
||||||
|
<th class="text-center" colspan="3">
|
||||||
|
#{AdminMessages['categories.details.subcategories.table.headings.actions']}
|
||||||
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
@ -249,6 +252,36 @@
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<c:if test="#{category.categoryOrder != 1}">
|
||||||
|
<form action="#{mvc.uri('CategoriesController#reorderSubCategory', {'categoryIdentifier': CategoryDetailsModel.identifier, 'subCategoryIdentifier': category.identifier})}"
|
||||||
|
method="post">
|
||||||
|
<input name="direction"
|
||||||
|
value="DECREASE"
|
||||||
|
type="hidden" />
|
||||||
|
<button class="btn btn-info"
|
||||||
|
type="submit">
|
||||||
|
<bootstrap:svgIcon icon="caret-up-fill" />
|
||||||
|
<span class="sr-only">#{AdminMessages['categories.details.subcategories.reorder.decrease']}</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</c:if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<c:if test="#{category.categoryOrder lt CategoryDetailsModel.subCategories.size()}">
|
||||||
|
<form action="#{mvc.uri('CategoriesController#reorderSubCategory', {'categoryIdentifier': CategoryDetailsModel.identifier, 'subCategoryIdentifier': category.identifier})}"
|
||||||
|
method="post">
|
||||||
|
<input name="direction"
|
||||||
|
value="INCREASE"
|
||||||
|
type="hidden" />
|
||||||
|
<button class="btn btn-info"
|
||||||
|
type="submit">
|
||||||
|
<bootstrap:svgIcon icon="caret-down-fill" />
|
||||||
|
<span class="sr-only">#{AdminMessages['categories.details.subcategories.reorder.increase']}</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</c:if>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<libreccm:deleteDialog
|
<libreccm:deleteDialog
|
||||||
actionTarget="#{mvc.uri('CategoriesController#removeSubCategory', {'categoryIdentifier': category.identifier})}"
|
actionTarget="#{mvc.uri('CategoriesController#removeSubCategory', {'categoryIdentifier': category.identifier})}"
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,7 @@
|
||||||
<th>
|
<th>
|
||||||
#{AdminMessages['categorysystems.details.categories.table.headings.abstract']}
|
#{AdminMessages['categorysystems.details.categories.table.headings.abstract']}
|
||||||
</th>
|
</th>
|
||||||
<th class="text-center">
|
<th class="text-center" colspan="3">
|
||||||
#{AdminMessages['categorysystems.details.categories.table.headings.actions']}
|
#{AdminMessages['categorysystems.details.categories.table.headings.actions']}
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
@ -380,6 +380,36 @@
|
||||||
</c:otherwise>
|
</c:otherwise>
|
||||||
</c:choose>
|
</c:choose>
|
||||||
</td>
|
</td>
|
||||||
|
<td>
|
||||||
|
<c:if test="#{category.categoryOrder != 0}">
|
||||||
|
<form action="#{mvc.uri('CategoriesController#reorderSubCategory', {'categoryIdentifier': CategorySystemDetailsModel.rootIdentifier, 'subCategoryIdentifier': category.identifier})}"
|
||||||
|
method="post">
|
||||||
|
<input name="direction"
|
||||||
|
type="hidden"
|
||||||
|
value="DECREASE" />
|
||||||
|
<button class="btn btn-info"
|
||||||
|
type="submit">
|
||||||
|
<bootstrap:svgIcon icon="caret-up-fill" />
|
||||||
|
<span class="sr-only">#{AdminMessages['categories.details.subcategories.reorder.decrease']}</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</c:if>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<c:if test="#{category.categoryOrder lt CategorySystemDetailsModel.categories.size()}">
|
||||||
|
<form action="#{mvc.uri('CategoriesController#reorderSubCategory', {'categoryIdentifier': CategorySystemDetailsModel.rootIdentifier, 'subCategoryIdentifier': category.identifier})}"
|
||||||
|
method="post">
|
||||||
|
<input name="direction"
|
||||||
|
value="INCREASE"
|
||||||
|
type="hidden" />
|
||||||
|
<button class="btn btn-info"
|
||||||
|
type="submit">
|
||||||
|
<bootstrap:svgIcon icon="caret-down-fill" />
|
||||||
|
<span class="sr-only">#{AdminMessages['categories.details.subcategories.reorder.increase']}</span>
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
</c:if>
|
||||||
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<libreccm:deleteDialog
|
<libreccm:deleteDialog
|
||||||
actionTarget="#{mvc.uri('CategoriesController#removeSubCategory', {'categoryIdentifier': category.identifier})}"
|
actionTarget="#{mvc.uri('CategoriesController#removeSubCategory', {'categoryIdentifier': category.identifier})}"
|
||||||
|
|
|
||||||
|
|
@ -451,3 +451,7 @@ categories.details.description.table.headings.actions=Actions
|
||||||
categories.details.description.table.headings.locale=Locale
|
categories.details.description.table.headings.locale=Locale
|
||||||
categories.details.description.table.headings.value=Value
|
categories.details.description.table.headings.value=Value
|
||||||
categorysystems.details.categories.table.headings.actions=Actions
|
categorysystems.details.categories.table.headings.actions=Actions
|
||||||
|
categories.invalid_direction.message=Invalid direction {0}. Valid direction are: INCREASE, DECREASE
|
||||||
|
categories.details.subcategories.table.headings.actions=Actions
|
||||||
|
categories.details.subcategories.reorder.decrease=Move up
|
||||||
|
categories.details.subcategories.reorder.increase=Move down
|
||||||
|
|
|
||||||
|
|
@ -451,3 +451,7 @@ categories.details.description.table.headings.actions=Aktionen
|
||||||
categories.details.description.table.headings.locale=Sprache
|
categories.details.description.table.headings.locale=Sprache
|
||||||
categories.details.description.table.headings.value=Wert
|
categories.details.description.table.headings.value=Wert
|
||||||
categorysystems.details.categories.table.headings.actions=Aktionen
|
categorysystems.details.categories.table.headings.actions=Aktionen
|
||||||
|
categories.invalid_direction.message=Ung\u00fcltiger Wert {0} f\u00fcr Parameter direction. G\u00fcltige Werte: INCREASE, DECREASE
|
||||||
|
categories.details.subcategories.table.headings.actions=Aktionen
|
||||||
|
categories.details.subcategories.reorder.decrease=Hoch
|
||||||
|
categories.details.subcategories.reorder.increase=Runter
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue