From: Roland Häder <roland@mxchange.org> Date: Tue, 31 Oct 2017 18:44:33 +0000 (+0100) Subject: Maybe cherry-pick: X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=113cd842d0c5b969d5a906f7b95581d8b4f1fff8;p=jfinancials-war.git Maybe cherry-pick: - added mini-links JSF tags for product categories and generic products - added form templates for above again - added views for listing both again - added navigation rules to faces-config.xml - rewrote converter to CDI "lookup" (programatic) which finally let the converter work without any EJB calls - added filtered list for categories and products - added product unit amount and type, like 1 liter - categories and products have now both i18n keys and not direct and untranslateable titles - rewrote + sorted renderGenericProduct() as products now have i18n keys - added menu entries Signed-off-by: Roland Häder <roland@mxchange.org> --- diff --git a/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java index 3a746f2c..1764c64f 100644 --- a/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/category/FinancialAdminCategoryWebRequestBean.java @@ -64,9 +64,9 @@ public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean imp private Boolean categoryShownInStatistics; /** - * Category categoryTitle + * Category categoryI18nKey */ - private String categoryTitle; + private String categoryI18nKey; /** * Parent category @@ -128,21 +128,21 @@ public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean imp } /** - * Getter for category title + * Getter for category i18n key * <p> - * @return the title + * @return Category i18n key */ - public String getCategoryTitle () { - return this.categoryTitle; + public String getCategoryI18nKey () { + return this.categoryI18nKey; } /** - * Setter for category title + * Setter for category i18n key * <p> - * @param categoryTitle the title to set + * @param categoryI18nKey Category i18n key */ - public void setCategoryTitle (final String categoryTitle) { - this.categoryTitle = categoryTitle; + public void setCategoryI18nKey (final String categoryI18nKey) { + this.categoryI18nKey = categoryI18nKey; } /** @@ -168,7 +168,7 @@ public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean imp */ private void clear () { // Clear all fields - this.setCategoryTitle(null); + this.setCategoryI18nKey(null); this.setParentCategory(null); } @@ -179,7 +179,7 @@ public class FinancialAdminCategoryWebRequestBean extends BaseFinancialsBean imp */ private Category createCategoryInstance () { // Create category - final Category category = new ProductCategory(this.getCategoryTitle(), this.getParentCategory(), this.getCategoryShownInStatistics()); + final Category category = new ProductCategory(this.getCategoryI18nKey(), this.getParentCategory(), this.getCategoryShownInStatistics()); // Return it return category; diff --git a/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java index d9d588c9..e45879a9 100644 --- a/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/category/FinancialCategoryWebRequestBean.java @@ -52,7 +52,7 @@ public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implemen /** * List of all categories */ - private List<Category> allCategories; + private final List<Category> allCategories; /** * EJB for general category stuff @@ -67,6 +67,11 @@ public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implemen @NamedCache (cacheName = "categoryCache") private Cache<Long, Category> categoryCache; + /** + * A list of filtered categories + */ + private List<Category> filteredCategories; + /** * Default constructor */ @@ -135,6 +140,26 @@ public class FinancialCategoryWebRequestBean extends BaseFinancialsBean implemen return category; } + /** + * Getter for filtered category list + * <p> + * @return Filtered category list + */ + @SuppressWarnings ("ReturnOfCollectionOrArrayField") + public List<Category> getFilteredCategories () { + return this.filteredCategories; + } + + /** + * Setter for filtered category list + * <p> + * @param filteredCategories Filtered category list + */ + @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter") + public void setFilteredCategories (final List<Category> filteredCategories) { + this.filteredCategories = filteredCategories; + } + /** * Initialization of this bean */ diff --git a/src/java/org/mxchange/jfinancials/beans/helper/FinancialsWebRequestHelperBean.java b/src/java/org/mxchange/jfinancials/beans/helper/FinancialsWebRequestHelperBean.java index e07d84d9..5592f369 100644 --- a/src/java/org/mxchange/jfinancials/beans/helper/FinancialsWebRequestHelperBean.java +++ b/src/java/org/mxchange/jfinancials/beans/helper/FinancialsWebRequestHelperBean.java @@ -42,6 +42,7 @@ import org.mxchange.jphone.events.mobile.created.ObservableCreatedMobileNumberEv import org.mxchange.jphone.model.phonenumbers.fax.DialableFaxNumber; import org.mxchange.jphone.model.phonenumbers.landline.DialableLandLineNumber; import org.mxchange.jphone.model.phonenumbers.mobile.DialableMobileNumber; +import org.mxchange.jproduct.model.category.Category; import org.mxchange.jproduct.model.product.Product; import org.mxchange.jusercore.events.user.created.CreatedUserEvent; import org.mxchange.jusercore.events.user.created.ObservableCreatedUserEvent; @@ -566,6 +567,31 @@ public class FinancialsWebRequestHelperBean extends BaseFinancialsBean implement return sb.toString(); } + /** + * Returns the product name and price. If null is provided, an empty string + * is returned. + * <p> + * @param product Product instance + * <p> + * @return Product name + */ + public String renderGenericProduct (final Product product) { + // Default is empty string, so let's get started + final StringBuilder sb = new StringBuilder(10); + + // Is a product set? + if (product instanceof Product) { + // Add name and price + sb.append(product.getProductI18nKey()); + sb.append(" ("); //NOI18N + sb.append(this.localizationController.formatCurrency(product.getProductGrossPrice())); + sb.append(")"); //NOI18N + } + + // Return it + return sb.toString(); + } + /** * Returns the headquarters address. If null is provided, an empty string is * returned. @@ -612,24 +638,29 @@ public class FinancialsWebRequestHelperBean extends BaseFinancialsBean implement } /** - * Returns the product name and price. If null is provided, an empty string - * is returned. + * Returns the category's i18n string translated. If null is provided, an + * empty string is returned. * <p> - * @param product Product instance + * @param category Product category instance * <p> - * @return Product name + * @return Category's i18n string translation */ - public String renderProduct (final Product product) { + public String renderProductCategory (final Category category) { // Default is empty string, so let's get started final StringBuilder sb = new StringBuilder(10); - // Is a product set? - if (product instanceof Product) { - // Add name and price - sb.append(product.getProductTitle()); - sb.append(" ("); //NOI18N - sb.append(this.localizationController.formatCurrency(product.getProductGrossPrice())); - sb.append(")"); //NOI18N + // Is a category set? + if (category instanceof Category) { + // Add title + sb.append(this.getMessageFromBundle(category.getCategoryI18nKey())); + + // Is a parent category set? + if (category.getParentCategory() instanceof Category) { + // Then add it in braces, too + sb.append(" ("); //NOI18N + sb.append(this.getMessageFromBundle(category.getParentCategory().getCategoryI18nKey())); + sb.append(")"); //NOI18N + } } // Return it diff --git a/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java index db8058be..842d3b1f 100644 --- a/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/product/FinancialAdminProductWebRequestBean.java @@ -81,8 +81,8 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl /** * Remote bean for products */ - @EJB (lookup = "java:global/jfinancial-ejb/adminProduct!org.mxchange.jproduct.model.product.AdminProductSessionBeanRemote") - private AdminProductSessionBeanRemote productRemoteBean; + @EJB (lookup = "java:global/jfinancials-ejb/adminProduct!org.mxchange.jproduct.model.product.AdminProductSessionBeanRemote") + private AdminProductSessionBeanRemote adminProductBean; /** * Product's tax rate @@ -90,9 +90,19 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl private Float productTaxRate; /** - * Property productTitle + * I18n key of product */ - private String productTitle; + private String productI18nKey; + + /** + * Product's unit amount + */ + private Float productUnitAmount; + + /** + * Product's unit type + */ + private String productUnitType; /** * Default constructor @@ -116,7 +126,7 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl try { // Call bean - updatedProduct = this.productRemoteBean.addGenericProduct(product); + updatedProduct = this.adminProductBean.addGenericProduct(product); } catch (final ProductAlreadyAddedException ex) { // Continue to throw throw new FaceletException(ex); @@ -130,18 +140,18 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl } /** - * Getter for product's available property + * Getter for product's available * <p> - * @return Product's available property + * @return Product's available */ public Boolean getProductAvailability () { return this.productAvailability; } /** - * Setter for product's available property + * Setter for product's available * <p> - * @param productAvailability Product's available property + * @param productAvailability Product's available */ public void setProductAvailability (final Boolean productAvailability) { this.productAvailability = productAvailability; @@ -238,21 +248,57 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl } /** - * Getter for product's title property + * Getter for product's i18n key + * <p> + * @return Product's i18n key + */ + public String getProductI18nKey () { + return this.productI18nKey; + } + + /** + * Setter for product's i18n key + * <p> + * @param productI18nKey Product's i18n key + */ + public void setProductI18nKey (final String productI18nKey) { + this.productI18nKey = productI18nKey; + } + + /** + * Getter for product's unit amount + * <p> + * @return Product's unit amount + */ + public Float getProductUnitAmount () { + return this.productUnitAmount; + } + + /** + * Setter for product's unit amount + * <p> + * @param productUnitAmount Product's unit amount + */ + public void setProductUnitAmount (final Float productUnitAmount) { + this.productUnitAmount = productUnitAmount; + } + + /** + * Getter for product's unit type * <p> - * @return Product's title + * @return Product's unit type */ - public String getProductTitle () { - return this.productTitle; + public String getProductUnitType () { + return this.productUnitType; } /** - * Setter for product's title property + * Setter for product's unit type * <p> - * @param productTitle Product's title + * @param productUnitType Product's unit type */ - public void setProductTitle (final String productTitle) { - this.productTitle = productTitle; + public void setProductUnitType (final String productUnitType) { + this.productUnitType = productUnitType; } /** @@ -264,7 +310,9 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl this.setProductNetPrice(null); this.setProductTaxRate(null); this.setProductGrossPrice(null); - this.setProductTitle(null); + this.setProductI18nKey(null); + this.setProductUnitAmount(null); + this.setProductUnitType(null); } /** @@ -274,11 +322,13 @@ public class FinancialAdminProductWebRequestBean extends BaseFinancialsBean impl */ private Product createProductInstance () { // Create product instance - final Product product = new GenericProduct(this.getProductTitle(), this.getProductGrossPrice(), this.getProductCurrencyCode(), this.getProductCategory(), this.getProductAvailability()); + final Product product = new GenericProduct(this.getProductI18nKey(), this.getProductGrossPrice(), this.getProductCurrencyCode(), this.getProductCategory(), this.getProductAvailability()); // Set all optional fields product.setProductNetPrice(this.getProductNetPrice()); product.setProductTaxRate(this.getProductTaxRate()); + product.setProductUnitAmount(this.getProductUnitAmount()); + product.setProductUnitType(this.getProductUnitType()); // Return it return product; diff --git a/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java b/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java index 88da637e..635cbe82 100644 --- a/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java +++ b/src/java/org/mxchange/jfinancials/beans/product/FinancialProductWebRequestBean.java @@ -51,10 +51,15 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement private static final long serialVersionUID = 58_137_539_530_279L; /** - * List for all available products + * List for all products */ private List<Product> allProducts; + /** + * List for filtered products + */ + private List<Product> filteredProducts; + /** * EJB for general product purposes */ @@ -137,6 +142,26 @@ public class FinancialProductWebRequestBean extends BaseFinancialsBean implement return product; } + /** + * Getter for filtered product list + * <p> + * @return Filtered product list + */ + @SuppressWarnings ("ReturnOfCollectionOrArrayField") + public List<Product> getFilteredProducts () { + return this.filteredProducts; + } + + /** + * Setter for filtered product list + * <p> + * @param filteredProducts Filtered product list + */ + @SuppressWarnings ("AssignmentToCollectionOrArrayFieldFromParameter") + public void setFilteredProducts (final List<Product> filteredProducts) { + this.filteredProducts = filteredProducts; + } + /** * Initialization of this bean */ diff --git a/src/java/org/mxchange/jfinancials/converter/generic_product/FinancialsGenericProductConverter.java b/src/java/org/mxchange/jfinancials/converter/generic_product/FinancialsGenericProductConverter.java index 7d03212d..5af8d5fd 100644 --- a/src/java/org/mxchange/jfinancials/converter/generic_product/FinancialsGenericProductConverter.java +++ b/src/java/org/mxchange/jfinancials/converter/generic_product/FinancialsGenericProductConverter.java @@ -16,15 +16,13 @@ */ package org.mxchange.jfinancials.converter.generic_product; -import javax.faces.application.FacesMessage; +import javax.enterprise.inject.spi.CDI; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; import javax.faces.convert.FacesConverter; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; +import org.mxchange.jfinancials.beans.product.FinancialProductWebRequestBean; import org.mxchange.jfinancials.beans.product.FinancialProductWebRequestController; import org.mxchange.jproduct.exceptions.product.ProductNotFoundException; import org.mxchange.jproduct.model.product.Product; @@ -46,16 +44,8 @@ public class FinancialsGenericProductConverter implements Converter<Product> { public Product getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) { // Is the instance there? if (PRODUCT_CONTROLLER == null) { - try { - // Not yet, attempt lookup - final Context initial = new InitialContext(); - - // Lookup EJB - PRODUCT_CONTROLLER = (FinancialProductWebRequestController) initial.lookup("java:global/jfinancials-ejb/productController!org.mxchange.jfinancials.beans.product.FinancialProductWebRequestController"); - } catch (final NamingException ex) { - // Throw it again - throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cannot lookup backing bean", ex.getMessage()), ex); - } + // Get bean from CDI directly + PRODUCT_CONTROLLER = CDI.current().select(FinancialProductWebRequestBean.class).get(); } // Is the value null or empty? diff --git a/src/java/org/mxchange/jfinancials/converter/product_category/FinancialsProductCategoryConverter.java b/src/java/org/mxchange/jfinancials/converter/product_category/FinancialsProductCategoryConverter.java index a1753d0b..983e8b3f 100644 --- a/src/java/org/mxchange/jfinancials/converter/product_category/FinancialsProductCategoryConverter.java +++ b/src/java/org/mxchange/jfinancials/converter/product_category/FinancialsProductCategoryConverter.java @@ -16,15 +16,12 @@ */ package org.mxchange.jfinancials.converter.product_category; -import javax.faces.application.FacesMessage; +import javax.enterprise.inject.spi.CDI; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.ConverterException; import javax.faces.convert.FacesConverter; -import javax.naming.Context; -import javax.naming.InitialContext; -import javax.naming.NamingException; import org.mxchange.jfinancials.beans.category.FinancialCategoryWebRequestBean; import org.mxchange.jfinancials.beans.category.FinancialCategoryWebRequestController; import org.mxchange.jproduct.exceptions.category.CategoryNotFoundException; @@ -47,16 +44,8 @@ public class FinancialsProductCategoryConverter implements Converter<Category> { public Category getAsObject (final FacesContext context, final UIComponent component, final String submittedValue) { // Is the instance there? if (CATEGORY_CONTROLLER == null) { - try { - // Not yet, attempt lookup - final Context initial = new InitialContext(); - - // Lookup EJB - CATEGORY_CONTROLLER = (FinancialCategoryWebRequestController) initial.lookup(String.format("java:module/%s", FinancialCategoryWebRequestBean.class.getSimpleName())); - } catch (final NamingException ex) { - // Throw it again - throw new ConverterException(new FacesMessage(FacesMessage.SEVERITY_ERROR, "Cannot lookup backing bean", ex.getMessage()), ex); - } + // Get bean from CDI directly + CATEGORY_CONTROLLER = CDI.current().select(FinancialCategoryWebRequestBean.class).get(); } // Is the value null or empty? diff --git a/web/WEB-INF/faces-config.xml b/web/WEB-INF/faces-config.xml index cab11327..b6471e27 100644 --- a/web/WEB-INF/faces-config.xml +++ b/web/WEB-INF/faces-config.xml @@ -128,6 +128,14 @@ <from-outcome>admin_list_company_employee</from-outcome> <to-view-id>/admin/employee/admin_employee_list.xhtml</to-view-id> </navigation-case> + <navigation-case> + <from-outcome>admin_list_category</from-outcome> + <to-view-id>/admin/category/admin_product_category_list.xhtml</to-view-id> + </navigation-case> + <navigation-case> + <from-outcome>admin_list_product</from-outcome> + <to-view-id>/admin/product/admin_generic_product_list.xhtml</to-view-id> + </navigation-case> <navigation-case> <from-outcome>admin_list_user</from-outcome> <to-view-id>/admin/user/admin_user_list.xhtml</to-view-id> @@ -873,6 +881,40 @@ <to-view-id>/admin/opening_time/admin_opening_time_delete.xhtml</to-view-id> </navigation-case> </navigation-rule> + <navigation-rule> + <from-view-id>/admin/category/admin_product_category_list.xhtml</from-view-id> + <navigation-case> + <from-outcome>admin_show_product_category</from-outcome> + <to-view-id>/admin/category/admin_product_category_show.xhtml</to-view-id> + </navigation-case> + <navigation-case> + <from-outcome>admin_edit_product_category</from-outcome> + <to-view-id>/admin/category/admin_product_category_edit.xhtml</to-view-id> + </navigation-case> + <navigation-case> + <from-outcome>admin_delete_product_category</from-outcome> + <to-view-id>/admin/category/admin_product_category_delete.xhtml</to-view-id> + </navigation-case> + <navigation-case> + <from-outcome>admin_assign_parent_category</from-outcome> + <to-view-id>/admin/category/admin_product_category_assign_parent.xhtml</to-view-id> + </navigation-case> + </navigation-rule> + <navigation-rule> + <from-view-id>/admin/product/admin_generic_product_list.xhtml</from-view-id> + <navigation-case> + <from-outcome>admin_show_generic_product</from-outcome> + <to-view-id>/admin/product/admin_generic_product_show.xhtml</to-view-id> + </navigation-case> + <navigation-case> + <from-outcome>admin_edit_generic_product</from-outcome> + <to-view-id>/admin/product/admin_generic_product_edit.xhtml</to-view-id> + </navigation-case> + <navigation-case> + <from-outcome>admin_delete_generic_product</from-outcome> + <to-view-id>/admin/product/admin_generic_product_delete.xhtml</to-view-id> + </navigation-case> + </navigation-rule> <!-- <factory> <exception-handler-factory> diff --git a/web/WEB-INF/product-links.jsf.taglib.xml b/web/WEB-INF/product-links.jsf.taglib.xml new file mode 100644 index 00000000..637991ce --- /dev/null +++ b/web/WEB-INF/product-links.jsf.taglib.xml @@ -0,0 +1,69 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!-- +Copyright (C) 2017 Roland Häder + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU Affero General Public License as +published by the Free Software Foundation, either version 3 of the +License, or (at your option) any later version. + +This program 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 Affero General Public License for more details. + +You should have received a copy of the GNU Affero General Public License +along with this program. If not, see <http://www.gnu.org/licenses/>. +--> +<facelet-taglib version="2.2" + xmlns="http://xmlns.jcp.org/xml/ns/javaee" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facelettaglibrary_2_2.xsd"> + <namespace>http://mxchange.org/jsf/jproduct/links</namespace> + <tag> + <tag-name>outputProductCategoryAdminMiniLinks</tag-name> + <description>This tag renders administrative "mini-links" for given category instance.</description> + <source>resources/tags/admin/links/mini/category/admin_product_category_links.tpl</source> + <attribute> + <name>category</name> + <description>The product category instance that provides the data for this tag.</description> + <required>true</required> + <type>org.mxchange.jproduct.model.category.Category</type> + </attribute> + <attribute> + <name>renderShowLink</name> + <description>Whether to render (default: true) "show product" link.</description> + <required>false</required> + <type>java.langBoolean</type> + </attribute> + <attribute> + <name>rendered</name> + <description>Whether this tag is being rendered by JSF engine (default: true).</description> + <required>false</required> + <type>java.lang.Boolean</type> + </attribute> + </tag> + <tag> + <tag-name>outputGenericProductAdminMiniLinks</tag-name> + <description>This tag renders administrative "mini-links" for given product instance.</description> + <source>resources/tags/admin/links/mini/product/admin_generic_product_links.tpl</source> + <attribute> + <name>product</name> + <description>The generic product instance that provides the data for this tag.</description> + <required>true</required> + <type>org.mxchange.jproduct.model.product.Product</type> + </attribute> + <attribute> + <name>renderShowLink</name> + <description>Whether to render (default: true) "show product" link.</description> + <required>false</required> + <type>java.langBoolean</type> + </attribute> + <attribute> + <name>rendered</name> + <description>Whether this tag is being rendered by JSF engine (default: true).</description> + <required>false</required> + <type>java.lang.Boolean</type> + </attribute> + </tag> +</facelet-taglib> diff --git a/web/WEB-INF/resources/tags/admin/links/mini/category/admin_product_category_links.tpl b/web/WEB-INF/resources/tags/admin/links/mini/category/admin_product_category_links.tpl new file mode 100644 index 00000000..b988c21c --- /dev/null +++ b/web/WEB-INF/resources/tags/admin/links/mini/category/admin_product_category_links.tpl @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<ui:composition + xmlns="http://www.w3.org/1999/xhtml" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:p="http://primefaces.org/ui"> + + <ui:fragment rendered="#{empty rendered or rendered}"> + <ul class="navbar-mini"> + <ui:fragment rendered="#{empty renderShowLink or renderShowLink}"> + <li class="navlink-mini"> + <p:link outcome="admin_show_product_category" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_PRODUCT_CATEGORY_TITLE}"> + <f:param name="categoryId" value="#{category.categoryId}" /> + </p:link> + </li> + </ui:fragment> + + <li class="navlink-mini"> + <p:link outcome="admin_edit_product_category" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_PRODUCT_CATEGORY_TITLE}"> + <f:param name="categoryId" value="#{category.categoryId}" /> + </p:link> + </li> + + <li class="navlink-mini"> + <p:link outcome="admin_delete_product_category"> + <h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_PRODUCT_CATEGORY_TITLE}" /> + <f:param name="categoryId" value="#{category.categoryId}" /> + </p:link> + </li> + </ul> + </ui:fragment> +</ui:composition> diff --git a/web/WEB-INF/resources/tags/admin/links/mini/product/admin_generic_product_links.tpl b/web/WEB-INF/resources/tags/admin/links/mini/product/admin_generic_product_links.tpl new file mode 100644 index 00000000..8d748ae2 --- /dev/null +++ b/web/WEB-INF/resources/tags/admin/links/mini/product/admin_generic_product_links.tpl @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<ui:composition + xmlns="http://www.w3.org/1999/xhtml" + xmlns:f="http://java.sun.com/jsf/core" + xmlns:h="http://java.sun.com/jsf/html" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:p="http://primefaces.org/ui"> + + <ui:fragment rendered="#{empty rendered or rendered}"> + <ul class="navbar-mini"> + <ui:fragment rendered="#{empty renderShowLink or renderShowLink}"> + <li class="navlink-mini"> + <p:link outcome="admin_show_product" value="#{msg.ADMIN_LINK_SHOW_SHORT}" title="#{msg.ADMIN_LINK_SHOW_GENERIC_PRODUCT_TITLE}"> + <f:param name="productId" value="#{product.productId}" /> + </p:link> + </li> + </ui:fragment> + + <li class="navlink-mini"> + <p:link outcome="admin_edit_product" value="#{msg.ADMIN_LINK_EDIT_SHORT}" title="#{msg.ADMIN_LINK_EDIT_GENERIC_PRODUCT_TITLE}"> + <f:param name="productId" value="#{product.productId}" /> + </p:link> + </li> + + <li class="navlink-mini"> + <p:link outcome="admin_delete_product"> + <h:outputText styleClass="link-danger" value="#{msg.ADMIN_LINK_DELETE_SHORT}" title="#{msg.ADMIN_LINK_DELETE_GENERIC_PRODUCT_TITLE}" /> + <f:param name="productId" value="#{product.productId}" /> + </p:link> + </li> + </ul> + </ui:fragment> +</ui:composition> diff --git a/web/WEB-INF/templates/admin/category/admin_form_category_data.tpl b/web/WEB-INF/templates/admin/category/admin_form_category_data.tpl new file mode 100644 index 00000000..c4d265cd --- /dev/null +++ b/web/WEB-INF/templates/admin/category/admin_form_category_data.tpl @@ -0,0 +1,47 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- +@TODO: title="#{project.ADMIN_PRODUCT_CATEGORY_DATA_LEGEND_TITLE}" +--> +<ui:composition + xmlns="http://www.w3.org/1999/xhtml" + xmlns:f="http://xmlns.jcp.org/jsf/core" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:p="http://primefaces.org/ui"> + + <p:fieldset legend="#{project.ADMIN_PRODUCT_CATEGORY_DATA_LEGEND}"> + <p:panelGrid layout="grid" columns="2" columnClasses="ui-grid-col-4,ui-grid-col-8" styleClass="table table-full ui-noborder"> + <p:outputLabel for="parentCategory" value="#{project.ADMIN_ASSIGN_PARENT_CATEGORY}" /> + <p:selectOneMenu + id="parentCategory" + value="#{adminCategoryController.parentCategory}" + filter="true" + filterMatchMode="contains" + title="#{project.ADMIN_ASSIGN_PARENT_CATEGORY_TITLE}" + > + <f:converter converterId="ProductCategoryConverter" /> + <f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" /> + <f:selectItems value="#{categoryController.allCategories()}" var="category" itemValue="#{category}" itemLabel="#{beanHelper.renderProductCategory(category)}" /> + </p:selectOneMenu> + + <p:outputLabel for="categoryI18nKey" value="#{project.ADMIN_ENTER_CATEGORY_I18N_KEY}" /> + <p:inputText + id="categoryI18nKey" + value="#{adminCategoryController.categoryI18nKey}" + size="10" + maxlength="255" + required="true" + requiredMessage="#{project.ADMIN_CATEGORY_I18N_KEY_REQUIRED}" + title="#{project.ADMIN_ENTER_CATEGORY_I18N_KEY_TITLE}" + /> + + <p:outputLabel for="categoryShownInStatistics" value="#{project.ADMIN_ENABLE_CATEGORY_IN_STATISTICS}" /> + <p:selectBooleanCheckbox + id="categoryShownInStatistics" + value="#{adminCategoryController.categoryShownInStatistics}" + required="true" + requiredMessage="#{project.ADMIN_ENABLE_CATEGORY_IN_STATISTICS_REQUIRED}" + title="#{project.ADMIN_ENABLE_CATEGORY_IN_STATISTICS_TITLE}" + /> + </p:panelGrid> + </p:fieldset> +</ui:composition> diff --git a/web/WEB-INF/templates/admin/menu/project.tpl b/web/WEB-INF/templates/admin/menu/project.tpl index a5f68a54..887a46b7 100644 --- a/web/WEB-INF/templates/admin/menu/project.tpl +++ b/web/WEB-INF/templates/admin/menu/project.tpl @@ -1,8 +1,6 @@ <?xml version="1.0" encoding="UTF-8" ?> <ui:composition xmlns="http://www.w3.org/1999/xhtml" - xmlns:f="http://xmlns.jcp.org/jsf/core" - xmlns:h="http://xmlns.jcp.org/jsf/html" xmlns:ui="http://xmlns.jcp.org/jsf/facelets" xmlns:p="http://primefaces.org/ui"> @@ -10,4 +8,9 @@ <p:menuitem title="#{project.ADMIN_LINK_LIST_RECEIPTS_TITLE}" outcome="admin_list_receipts" value="#{project.ADMIN_LINK_LIST_RECEIPTS}" /> <p:menuitem title="#{project.ADMIN_LINK_LIST_RECEIPT_ITEMS_TITLE}" outcome="admin_list_receipt_items" value="#{project.ADMIN_LINK_LIST_RECEIPT_ITEMS}" /> </p:submenu> + + <p:submenu label="#{project.ADMIN_MENU_PRODUCTS_CATEGORIES_TITLE}"> + <p:menuitem title="#{project.ADMIN_LINK_LIST_GENERIC_PRODUCTS_TITLE}" outcome="admin_list_product" value="#{project.ADMIN_LINK_LIST_GENERIC_PRODUCTS}" /> + <p:menuitem title="#{project.ADMIN_LINK_LIST_CATEGORIES_TITLE}" outcome="admin_list_category" value="#{project.ADMIN_LINK_LIST_CATEGORIES}" /> + </p:submenu> </ui:composition> diff --git a/web/WEB-INF/templates/admin/product/admin_form_product_data.tpl b/web/WEB-INF/templates/admin/product/admin_form_product_data.tpl new file mode 100644 index 00000000..2587060e --- /dev/null +++ b/web/WEB-INF/templates/admin/product/admin_form_product_data.tpl @@ -0,0 +1,80 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<!-- +@TODO: title="#{project.ADMIN_GENERIC_PRODUCT_DATA_LEGEND_TITLE}" +--> +<ui:composition + xmlns="http://www.w3.org/1999/xhtml" + xmlns:product="http://mxchange.org/jsf/jproduct/widgets" + xmlns:f="http://xmlns.jcp.org/jsf/core" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:p="http://primefaces.org/ui"> + + <p:fieldset legend="#{project.ADMIN_GENERIC_PRODUCT_DATA_LEGEND}"> + <p:panelGrid layout="grid" columns="2" columnClasses="ui-grid-col-4,ui-grid-col-8" styleClass="table table-full ui-noborder"> + <p:outputLabel for="productCategory" value="#{project.ADMIN_ASSIGN_PRODUCT_CATEGORY}" /> + <p:selectOneMenu + id="productCategory" + value="#{adminProductController.productCategory}" + filter="true" + filterMatchMode="contains" + required="true" + requiredMessage="#{project.ADMIN_PRODUCT_CATEGORY_REQUIRED}" + title="#{project.ADMIN_ASSIGN_PRODUCT_CATEGORY_TITLE}" + > + <f:converter converterId="ProductCategoryConverter" /> + <f:selectItem itemValue="#{null}" itemLabel="#{msg.PLEASE_SELECT}" noSelectionOption="true" itemDisabled="true" /> + <f:selectItems value="#{categoryController.allCategories()}" var="category" itemValue="#{category}" itemLabel="#{beanHelper.renderProductCategory(category)}" /> + </p:selectOneMenu> + + <p:outputLabel for="productI18nKey" value="#{project.ADMIN_ENTER_PRODUCT_I18N_KEY}" /> + <p:inputText + id="productI18nKey" + value="#{adminProductController.productI18nKey}" + size="10" + maxlength="255" + required="true" + requiredMessage="#{project.ADMIN_PRODUCT_I18N_KEY_REQUIRED}" + title="#{project.ADMIN_ENTER_PRODUCT_I18N_KEY_TITLE}" + /> + + <p:outputLabel for="productAvailability" value="#{project.ADMIN_ENABLE_PRODUCT_AVAILABILITY}" /> + <p:selectBooleanCheckbox + id="productAvailability" + value="#{adminProductController.productAvailability}" + required="true" + requiredMessage="#{project.ADMIN_GENERIC_PROJECT_AVAILABILITY_REQUIRED}" + title="#{project.ADMIN_ENABLE_PRODUCT_AVAILABILITY_TITLE}" + /> + + <p:outputLabel value="#{project.ADMIN_ENTER_PRODUCT_PRICE}" /> + <product:inputProductPricePanelGrid targetController="#{adminProductController}" /> + + <p:outputLabel for="productCurrencyCode" value="#{project.ADMIN_ENTER_PRODUCT_CURRENCY_CODE}" /> + <p:inputText + id="productCurrencyCode" + value="#{adminProductController.productCurrencyCode}" + size="3" + maxlength="3" + title="#{project.ADMIN_ENTER_PRODUCT_CURRENCY_CODE_TITLE}" + /> + + <p:outputLabel for="productUnitAmount" value="#{project.ADMIN_ENTER_PRODUCT_UNIT_AMOUNT}" /> + <p:inputNumber + id="productUnitAmount" + value="#{adminProductController.productUnitAmount}" + decimalSeparator="," + thousandSeparator="." + title="#{project.ADMIN_ENTER_PRODUCT_UNIT_AMOUNT_TITLE}" + /> + + <p:outputLabel for="productUnitType" value="#{project.ADMIN_ENTER_PRODUCT_UNIT_TYPE}" /> + <p:inputText + id="productUnitType" + value="#{adminProductController.productUnitType}" + size="10" + maxlength="255" + title="#{project.ADMIN_ENTER_PRODUCT_UNIT_TYPE_TITLE}" + /> + </p:panelGrid> + </p:fieldset> +</ui:composition> diff --git a/web/WEB-INF/web.xml b/web/WEB-INF/web.xml index dbce861c..3e85fbc2 100644 --- a/web/WEB-INF/web.xml +++ b/web/WEB-INF/web.xml @@ -30,7 +30,7 @@ <context-param> <description>Generic custom JSF tags library</description> <param-name>javax.faces.FACELETS_LIBRARIES</param-name> - <param-value>/WEB-INF/widgets.jsf.taglib.xml;/WEB-INF/links.jsf.taglib.xml;/WEB-INF/project-links.jsf.taglib.xml;/WEB-INF/product.jsf.taglib.xml</param-value> + <param-value>/WEB-INF/widgets.jsf.taglib.xml;/WEB-INF/links.jsf.taglib.xml;/WEB-INF/project-links.jsf.taglib.xml;/WEB-INF/product.jsf.taglib.xml;/WEB-INF/product-links.jsf.taglib.xml</param-value> </context-param> <context-param> <description>Project stage</description> diff --git a/web/admin/category/admin_product_category_list.xhtml b/web/admin/category/admin_product_category_list.xhtml new file mode 100644 index 00000000..1796183a --- /dev/null +++ b/web/admin/category/admin_product_category_list.xhtml @@ -0,0 +1,128 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<ui:composition template="/WEB-INF/templates/admin/admin_base.tpl" + xmlns="http://www.w3.org/1999/xhtml" + xmlns:product-links="http://mxchange.org/jsf/jproduct/links" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:h="http://xmlns.jcp.org/jsf/html" + xmlns:f="http://xmlns.jcp.org/jsf/core" + xmlns:p="http://primefaces.org/ui"> + + <ui:define name="document_admin_title"> + <h:outputText value="#{project.PAGE_TITLE_ADMIN_LIST_PRODUCT_CATEGORY}" /> + </ui:define> + + <ui:define name="content_header"> + <h:outputText value="#{project.CONTENT_TITLE_ADMIN_LIST_PRODUCT_CATEGORY}" /> + </ui:define> + + <ui:define name="content"> + <h:form id="form-list-categories"> + <p:dataTable + id="table-list-categories" + var="category" + value="#{categoryController.allCategories()}" + tableStyleClass="table table-full" + paginator="true" + paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" + filteredValue="#{categoryController.filteredCategories}" + rows="10" + reflow="true" + resizableColumns="true" + rowsPerPageTemplate="5,10,20,50,100" + sortMode="multiple" + summary="#{project.TABLE_SUMMARY_ADMIN_LIST_PRODUCT_CATEGORIES}" + emptyMessage="#{project.ADMIN_EMPTY_LIST_PRODUCT_CATEGORIES}" + widgetVar="categoryList" + > + + <f:facet name="header"> + <p:panelGrid columns="2" columnClasses="ui-grid-col-10,ui-grid-col-2" layout="grid" styleClass="ui-noborder ui-transparent-widget"> + <h:outputText value="#{project.ADMIN_LIST_PRODUCT_CATEGORIES_HEADER}" /> + + <h:panelGroup> + <p:commandButton id="toggler" type="button" value="#{msg.SELECT_SHOWN_COLUMNS}" styleClass="column-selector" /> + <p:columnToggler datasource="table-list-categories" trigger="toggler" /> + </h:panelGroup> + </p:panelGrid> + </f:facet> + + <p:column headerText="#{msg.ADMIN_HEADER_ID_NUMBER}" sortBy="#{category.categoryId}" filterable="false"> + <p:link outcome="admin_show_product_category" title="#{project.ADMIN_LINK_SHOW_PRODUCT_CATEGORY_TITLE}" value="#{category.categoryId}"> + <f:param name="categoryId" value="#{category.categoryId}" /> + </p:link> + </p:column> + + <p:column headerText="#{msg.ADMIN_HEADER_I18N_KEY}" sortBy="#{category.categoryI18nKey}" filterBy="#{category.categoryI18nKey}" filterMatchMode="contains"> + <h:outputText value="#{local[category.categoryI18nKey]}" /> + </p:column> + + <p:column headerText="#{project.ADMIN_HEADER_ASSIGNED_PARENT_CATEGORY}" sortBy="#{category.parentCategory.categoryI18nKey}" filterBy="#{category.parentCategory}" filterMatchMode="in"> + <f:facet name="filter"> + <p:selectCheckboxMenu + filter="true" + filterMatchMode="contains" + label="#{project.LABEL_PRODUCT_CATEGORIES}" + onchange="PF('categoryList').filter()" + updateLabel="true" + title="#{project.FILTER_BY_MULTIPLE_PRODUCT_CATEGORIES_TITLE}" + > + <f:converter converterId="ProductCategoryConverter" /> + <f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" /> + <f:selectItems value="#{categoryController.allCategories()}" var="category" itemValue="#{category}" itemLabel="#{beanHelper.renderProductCategory(category)}" /> + </p:selectCheckboxMenu> + </f:facet> + + <p:link outcome="admin_show_product_category" title="#{project.ADMIN_LINK_SHOW_PRODUCT_CATEGORY_TITLE}" value="#{category.parentCategory.categoryId}" rendered="#{not empty category.parentCategory}"> + <f:param name="categoryId" value="#{category.parentCategory.categoryId}" /> + </p:link> + + <p:link outcome="admin_assign_parent_category" title="#{project.ADMIN_LINK_ASSIGN_PARENT_CATEGORY_TITLE}" value="#{msg.ADMIN_NOT_ASSIGNED}" rendered="#{empty category.parentCategory}"> + <f:param name="categoryId" value="#{category.categoryId}" /> + </p:link> + </p:column> + + <p:column headerText="#{msg.ADMIN_HEADER_ENTRY_CREATED}" sortBy="#{category.categoryCreated}" filterable="false"> + <h:outputText id="categoryCreated" value="#{category.categoryCreated.time}"> + <f:convertDateTime for="categoryCreated" type="both" timeStyle="short" dateStyle="short" /> + </h:outputText> + </p:column> + + <p:column headerText="#{msg.ADMIN_HEADER_ACTION_LINKS}" sortable="false" filterable="false"> + <product-links:outputProductCategoryAdminMiniLinks category="#{category}" /> + </p:column> + </p:dataTable> + </h:form> + + <h:form> + <p:panelGrid columns="1" styleClass="table table-full" layout="grid"> + <f:facet name="header"> + <h:outputText value="#{project.ADMIN_ADD_PRODUCT_CATEGORY_TITLE}" /> + </f:facet> + + <h:panelGroup styleClass="para" layout="block"> + <h:outputText value="#{project.ADMIN_ADD_PRODUCT_CATEGORY_MINIMUM_DATA}" /> + </h:panelGroup> + + <ui:include src="/WEB-INF/templates/admin/category/admin_form_category_data.tpl" /> + + <f:facet name="footer"> + <p:panelGrid columns="2" layout="grid"> + <p:commandButton + styleClass="reset" + type="reset" + value="#{msg.BUTTON_RESET_FORM}" + /> + + <p:commandButton + styleClass="submit" + type="submit" + value="#{project.BUTTON_ADMIN_ADD_PRODUCT_CATEGORY}" + action="#{adminCategoryController.addCategory()}" + update=":master:form-list-categories:table-list-categories" + /> + </p:panelGrid> + </f:facet> + </p:panelGrid> + </h:form> + </ui:define> +</ui:composition> diff --git a/web/admin/product/admin_generic_product_list.xhtml b/web/admin/product/admin_generic_product_list.xhtml new file mode 100644 index 00000000..bcaa8190 --- /dev/null +++ b/web/admin/product/admin_generic_product_list.xhtml @@ -0,0 +1,135 @@ +<?xml version="1.0" encoding="UTF-8" ?> +<ui:composition template="/WEB-INF/templates/admin/admin_base.tpl" + xmlns="http://www.w3.org/1999/xhtml" + xmlns:product-links="http://mxchange.org/jsf/jproduct/links" + xmlns:ui="http://xmlns.jcp.org/jsf/facelets" + xmlns:h="http://xmlns.jcp.org/jsf/html" + xmlns:f="http://xmlns.jcp.org/jsf/core" + xmlns:p="http://primefaces.org/ui"> + + <ui:define name="document_admin_title"> + <h:outputText value="#{project.PAGE_TITLE_ADMIN_LIST_GENERIC_PRODUCT}" /> + </ui:define> + + <ui:define name="content_header"> + <h:outputText value="#{project.CONTENT_TITLE_ADMIN_LIST_GENERIC_PRODUCT}" /> + </ui:define> + + <ui:define name="content"> + <h:form id="form-list-products"> + <p:dataTable + id="table-list-products" + var="product" + value="#{productController.allProducts()}" + tableStyleClass="table table-full" + paginator="true" + paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" + filteredValue="#{productController.filteredProducts}" + rows="10" + reflow="true" + resizableColumns="true" + rowsPerPageTemplate="5,10,20,50,100" + sortMode="multiple" + summary="#{project.TABLE_SUMMARY_ADMIN_LIST_GENERIC_PRODUCTS}" + emptyMessage="#{project.ADMIN_EMPTY_LIST_GENERIC_PRODUCTS}" + widgetVar="productList" + > + + <f:facet name="header"> + <p:panelGrid columns="2" columnClasses="ui-grid-col-10,ui-grid-col-2" layout="grid" styleClass="ui-noborder ui-transparent-widget"> + <h:outputText value="#{project.ADMIN_LIST_GENERIC_PRODUCTS_HEADER}" /> + + <h:panelGroup> + <p:commandButton id="toggler" type="button" value="#{msg.SELECT_SHOWN_COLUMNS}" styleClass="column-selector" /> + <p:columnToggler datasource="table-list-products" trigger="toggler" /> + </h:panelGroup> + </p:panelGrid> + </f:facet> + + <p:column headerText="#{msg.ADMIN_HEADER_ID_NUMBER}" sortBy="#{product.productId}" filterable="false"> + <p:link outcome="admin_show_generic_product" title="#{project.ADMIN_LINK_SHOW_GENERIC_PRODUCT_TITLE}" value="#{product.productId}"> + <f:param name="productId" value="#{product.productId}" /> + </p:link> + </p:column> + + <p:column headerText="#{project.ADMIN_HEADER_I18N_KEY}" sortBy="#{product.productI18nKey}" filterBy="#{product.productI18nKey}" filterMatchMode="contains"> + <h:outputText value="#{product.productI18nKey}" /> + </p:column> + + <p:column headerText="#{project.ADMIN_HEADER_ASSIGNED_PRODUCT_CATEGORY}" sortBy="#{product.productCategory.categoryI18nKey}" filterBy="#{product.productCategory}" filterMatchMode="in"> + <f:facet name="filter"> + <p:selectCheckboxMenu + filter="true" + filterMatchMode="contains" + label="#{project.LABEL_PRODUCT_CATEGORIES}" + onchange="PF('productList').filter()" + updateLabel="true" + title="#{project.FILTER_BY_MULTIPLE_PRODUCT_CATEGORIES_TITLE}" + > + <f:converter converterId="ProductCategoryConverter" /> + <f:selectItem itemValue="#{null}" itemLabel="#{msg.NONE_SELECTED}" /> + <f:selectItems value="#{categoryController.allCategories()}" var="category" itemValue="#{category}" itemLabel="#{beanHelper.renderProductCategory(category)}" /> + </p:selectCheckboxMenu> + </f:facet> + + <p:link outcome="admin_show_product_category" title="#{project.ADMIN_LINK_SHOW_GENERIC_PRODUCT_CATEGORY_TITLE}" value="#{product.productCategory.categoryId}"> + <f:param name="categoryId" value="#{product.productCategory.categoryId}" /> + </p:link> + </p:column> + + <p:column headerText="#{project.ADMIN_HEADER_PRODUCT_GROSS_PRICE}" sortBy="#{product.productAvailability}" filterBy="#{product.productGrossPrice}" filterMatchMode="choose"> + <h:outputText value="#{product.productGrossPrice}"> + <!-- @TODO Hard-coded EUR again --> + <f:convertNumber type="currency" currencyCode="EUR" /> + </h:outputText> + </p:column> + + <p:column headerText="#{project.ADMIN_HEADER_PRODUCT_AVAILABILITY}" sortBy="#{product.productAvailability}" filterBy="#{product.productAvailability}" filterMatchMode=""> + <h:outputText value="#{product.productAvailability ? msg.CHOICE_YES : msg.CHOICE_NO}" /> + </p:column> + + <p:column headerText="#{msg.ADMIN_HEADER_ENTRY_CREATED}" sortBy="#{product.productCreated}" filterable="false"> + <h:outputText id="productCreated" value="#{product.productCreated.time}"> + <f:convertDateTime for="productCreated" type="both" timeStyle="short" dateStyle="short" /> + </h:outputText> + </p:column> + + <p:column headerText="#{msg.ADMIN_HEADER_ACTION_LINKS}" sortable="false" filterable="false"> + <product-links:outputGenericProductAdminMiniLinks product="#{product}" /> + </p:column> + </p:dataTable> + </h:form> + + <h:form> + <p:panelGrid columns="1" styleClass="table table-full" layout="grid"> + <f:facet name="header"> + <h:outputText value="#{project.ADMIN_ADD_GENERIC_PRODUCT_TITLE}" /> + </f:facet> + + <h:panelGroup styleClass="para" layout="block"> + <h:outputText value="#{project.ADMIN_ADD_GENERIC_PRODUCT_MINIMUM_DATA}" /> + </h:panelGroup> + + <ui:include src="/WEB-INF/templates/admin/product/admin_form_product_data.tpl" /> + + <f:facet name="footer"> + <p:panelGrid columns="2" layout="grid"> + <p:commandButton + styleClass="reset" + type="reset" + value="#{msg.BUTTON_RESET_FORM}" + /> + + <p:commandButton + styleClass="submit" + type="submit" + value="#{project.BUTTON_ADMIN_ADD_GENERIC_PRODUCT}" + action="#{adminProductController.addProduct()}" + update=":master:form-list-products:table-list-products" + /> + </p:panelGrid> + </f:facet> + </p:panelGrid> + </h:form> + </ui:define> +</ui:composition>