Tab for editing shopping categories completed.

This commit is contained in:
Tim Holloway 2022-01-14 17:27:26 -05:00
parent 1290c66055
commit 75a8487cfb
6 changed files with 306 additions and 188 deletions

View File

@ -12,7 +12,6 @@ import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.ReorderEvent;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@ -151,9 +150,9 @@ public class ShoppingListBean implements Serializable {
}
}
private List<Shopcat> shopcatList;
private List<String> shopcatList;
public List<Shopcat> getShopcatList() {
public List<String> getShopcatList() {
if (shopcatList == null) {
shopcatList = loadShopcatList();
}
@ -163,9 +162,9 @@ public class ShoppingListBean implements Serializable {
@Inject
ShopcatRepository shopcatRepository;
private List<Shopcat> loadShopcatList() {
return shopcatRepository
.findAllByOrderByShopcategoryAsc();
private List<String> loadShopcatList() {
return shopcatRepository.findDistinctCategoryNative();
// .findAllByOrderByShopcategoryAsc();
}
private Shopcat xeditShopcat = new Shopcat();
@ -180,19 +179,19 @@ public class ShoppingListBean implements Serializable {
}
public void doEditShopcat(int scId) {
xeditShopcat = null;
final List<Shopcat> scl = getShopcatList();
for (Shopcat sc : scl) {
if (sc.getId() == scId) {
xeditShopcat = sc;
this.oldShopcategoryName = sc.getShopcategory();
if (sc.getPosition() == null) {
sc.setPosition(0);
}
return;
}
}
log.error("SHOPCAT " + scId + " NOT FOUND");
// xeditShopcat = null;
// final List<Shopcat> scl = getShopcatList();
// for (Shopcat sc : scl) {
// if (sc.getId() == scId) {
// xeditShopcat = sc;
// this.oldShopcategoryName = sc.getShopcategory();
// if (sc.getPosition() == null) {
// sc.setPosition(0);
// }
// return;
// }
// }
// log.error("SHOPCAT " + scId + " NOT FOUND");
}
public void ajaxOnClickShopcatIngkey() {
@ -202,12 +201,103 @@ public class ShoppingListBean implements Serializable {
}
/**
* Updates all ingredient keys for shopcat name-change.
* Note that once done, this cannot be undone!
* Updates all ingredient keys for shopcat name-change. Note
* that once done, this cannot be undone!
*/
public void ajaxOnClickShopcat() {
this.shopcatRepository.UpdateShopcats(
this.oldShopcategoryName, xeditShopcat.getShopcategory());
this.oldShopcategoryName,
xeditShopcat.getShopcategory());
this.shopcatList = null;
}
// ===
private String selectedShopcat;
/**
* @return the selectedShopcat
*/
public String getSelectedShopcat() {
return selectedShopcat;
}
/**
* @param selectedShopcat the selectedShopcat to set
*/
public void setSelectedShopcat(String selectedShopcat) {
this.selectedShopcat = selectedShopcat;
this.ingkeyList = null;
}
private List<String> selectedIngkey;
/**
* @return the selectedIngkey
*/
public List<String> getSelectedIngkey() {
return selectedIngkey;
}
/**
* @param selectedIngkey the selectedIngkey to set
*/
public void setSelectedIngkey(List<String> selectedIngkey) {
this.selectedIngkey = selectedIngkey;
}
private List<String> ingkeyList;
/**
* @return the ingkeyList
*/
public List<String> getIngkeyList() {
if (ingkeyList == null) {
ingkeyList = loadIngkeyListFor(selectedShopcat);
}
return ingkeyList;
}
private List<String> loadIngkeyListFor(
String selectedShopcat2) {
List<String> list = this.shopcatRepository
.findByIngkeySorted(selectedShopcat2);
return list;
}
private String newShopcat;
/**
* @return the newShopcat
*/
public String getNewShopcat() {
return newShopcat;
}
/**
* @param newShopcat the newShopcat to set
*/
public void setNewShopcat(String newShopcat) {
this.newShopcat = newShopcat;
}
public List<String> suggestShopcat(String query) {
return this.shopcatList;
}
public void doChangeShopcat() {
String oldCat = this.getSelectedShopcat();
String newCat = this.getNewShopcat();
if (oldCat.equals(newCat)) {
return; // effective NO-OP
}
newCat = newCat.trim();
if ( StringUtils.isBlank(newCat)) {
this.shopcatRepository
.deleteShopcatFor(this.getSelectedIngkey());
} else {
this.shopcatRepository
.updateShopcatFor(newCat, this.getSelectedIngkey());
}
}
}

View File

@ -12,8 +12,8 @@ import org.springframework.stereotype.Repository;
import com.mousetech.gourmetj.persistence.model.Shopcat;
/**
* JpaRepository for Shopping Categories, which relate ManyToOne to Ingredient.
* Service method is @see RecipeService
* JpaRepository for Shopping Categories, which relate ManyToOne
* to Ingredient. Service method is @see RecipeService
*
* @author timh
* @since Dec 28, 2021
@ -34,11 +34,24 @@ public interface ShopcatRepository
@Transactional
@Query(value = "UPDATE Shopcat set shopcategory = :newCatname WHERE shopcategory = :oldCatname")
@Modifying
public int UpdateShopcats(String oldCatname, String newCatname);
public int UpdateShopcats(String oldCatname,
String newCatname);
public Shopcat findShopcatByIngkey(String ingkey);
public void deleteByIngkey(String key);
public List<Shopcat> findAllByOrderByShopcategoryAsc();
@Query(value = "SELECT s.ingkey FROM Shopcat s WHERE s.shopcategory = :shopcat ORDER BY s.ingkey")
public List<String> findByIngkeySorted(String shopcat);
@Transactional
@Query(value = "UPDATE Shopcat set shopcategory = :newCat WHERE ingkey IN :selectedIngkey")
@Modifying
public void updateShopcatFor(String newCat, List<String> selectedIngkey);
@Transactional
@Query(value = "DELETE Shopcat WHERE ingkey IN :selectedIngkey")
@Modifying public void deleteShopcatFor(List<String> selectedIngkey);
}

View File

@ -25,11 +25,15 @@
<ui:insert name="content">
<ui:include src="content.xhtml" />
</ui:insert>
<!-- -->
<div id="footer">
(C) 2021 Tim Holloway, Licensed under the <a
href="http://www.apache.org/licenses/LICENSE-2.0"
>Apache License, Version 2.0</a>.
<p>Based on Gourmet Recipe Manager by T. Hinkle</p>
<p>Based on Gourmet Recipe Manager by T.
Hinkle</p>
</div>
<!-- -->
<h:form id="frmTimeout">
<p:idleMonitor
timeout="#{userSession.sessionTimeoutInterval}"

View File

@ -1,121 +1,96 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
<html xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://xmlns.jcp.org/jstl"
>
<!-- === Edit ingkey/shopcat === -->
<h:form id="frmIsk1">
<p:dataTable id="tblShopcats"
style="width: 300px"
<h:form id="frmIsk">
<p:panelGrid>
<p:row>
<p:column>
<p:outputLabel for="ctlScSel"
value="Shopping Category"
/>
</p:column>
<p:column>
<p:outputLabel for="ctlIngkeySel"
value="Ingredient Key"
/>
</p:column>
</p:row>
<p:row style="vertical-align: top">
<p:column>
<p:selectOneListbox id="ctlScSel"
style="width: 240px"
value="#{shoppingListBean.selectedShopcat}"
>
<f:selectItems
value="#{shoppingListBean.shopcatList}"
sortBy="#{item.shopcategory}" var="item"
/>
<p:ajax update="ctlIngkeySel" event="change" />
</p:selectOneListbox>
</p:column>
<p:column>
<h:selectManyListbox id="ctlIngkeySel"
style="width: 240px"
value="#{shoppingListBean.selectedIngkey}"
label="Ingcat"
>
<f:facet name="header">
<h:outputText
value="Ingredient Keys/Shopping Categories" />
</f:facet>
<p:headerRow>
<f:selectItems
value="#{shoppingListBean.ingkeyList}"
/>
<p:ajax event="change" update="ctlChangeCat"/>
</h:selectManyListbox>
</p:column>
</p:row>
<p:row>
<p:column>
<h:outputText id="ctlCatname"
value="#{item.shopcategory}" />
<p:outputLabel
value="Change shopping category to:"
/>
</p:column>
<p:column style="width: 5em">
<p:commandButton
id="ctlEditCat" value="Rename"
action="#{shoppingListBean.doEditShopcat(item.id)}"
onclick="PF('dlgEditShopcat').show()"
update="frmEscat:pnlData" />
</p:column>
</p:headerRow>
<p:column>
<h:outputText value="#{item.ingkey}"
onclick="clickIngkeyName()" />
<p:autoComplete
value="#{shoppingListBean.newShopcat}"
autoSelection="false" forceSelection="false"
maxResults="12"
completeMethod="#{shoppingListBean.suggestShopcat}"
/>
</p:column>
<p:column style="width: 5em">
<p:commandButton
id="ctlEditIngkey" value="Move"
action="#{shoppingListBean.doEditShopcat(item.id)}"
onclick="PF('dlgEditIngkey').show()"
update="frmIngkey:pnlData" />
</p:row>
<p:row>
<p:column>
<p:commandButton id="ctlChangeCat" value="Change..."
disabled="#{empty shoppingListBean.selectedIngkey}"
onclick="PF('dlgOkRecat').show()"
/>
</p:column>
</p:dataTable>
<p:column>
<h:outputText value="" />
</p:column>
</p:row>
</p:panelGrid>
</h:form>
<!-- -->
<h:form id="frmEscat">
<p:dialog id="dlgEditShopcat"
widgetVar="dlgEditShopcat"
header="Edit/Rename Shopping Category"
closeOnEscape="true"
<h:form id="frmDelete">
<p:confirmDialog closable="false" id="dlgOkRecat"
header="Confirm Change - CANNOT UNDO"
message="OK to CHANGE Shopping Category for these Ingredient Keys?"
severity="alert" widgetVar="dlgOkRecat"
style="z-index: 25000"
>
<p:panelGrid id="pnlData" columns="2"
styleClass="ui-panelgrid-blank"
>
<p:outputLabel for="@next"
value="Shopping Category" />
<p:inputText id="ctlDlgShopcatName"
label="Position" required="true"
value="#{shoppingListBean.editShopcat.shopcategory}" />
<p:outputLabel for="@next"
value="Position" />
<p:inputText
id="ctlDlgShopcatPosition" type="number"
required="true" size="3"
value="#{shoppingListBean.editShopcat.position}" />
</p:panelGrid>
<p:panelGrid columns="2"
style="width: 100%"
styleClass="ui-panelgrid-blank"
>
<p:commandButton id="scDlgOK"
value="OK" style="width: 6em"
action="#{shoppingListBean.ajaxOnClickShopcat}"
update="frmIsk1:tblShopcats"
process="@this pnlData"
oncomplete="PF('dlgEditShopcat').hide()" />
<p:commandButton id="scDlgCan"
value="Cancel" style="width: 6em"
onclick="PF('dlgEditShopcat').hide()" />
</p:panelGrid>
</p:dialog>
</h:form>
<!-- -->
<h:form id="frmIngkey">
<p:dialog id="dlgEditIngkey"
widgetVar="dlgEditIngkey"
header="Edit/Rename Shopping Category for Ingredient Key"
closeOnEscape="true"
>
<p:panelGrid id="pnlData" columns="2"
styleClass="ui-panelgrid-blank"
>
<p:outputLabel for="@next"
value="Ingredient Key" />
<h:outputText
id="ctlDlgIngKeyIngkey"
value="#{shoppingListBean.editShopcat.ingkey}" />
<p:outputLabel for="@next"
value="Shopping Category" />
<p:inputText
id="ctlDlgIngkeyShopcatName" label="Position"
required="true"
value="#{shoppingListBean.editShopcat.shopcategory}" />
</p:panelGrid>
<p:panelGrid columns="2"
style="width: 100%"
styleClass="ui-panelgrid-blank"
>
<p:commandButton id="ingkDlgOK"
value="OK" style="width: 6em"
action="#{shoppingListBean.ajaxOnClickShopcatIngkey}"
update="frmIsk1:tblShopcats"
process="@this pnlData"
oncomplete="PF('dlgEditIngkey').hide()" />
<p:commandButton id="ingkDlgCan"
value="Cancel" style="width: 6em"
onclick="PF('dlgEditIngkey').hide()" />
</p:panelGrid>
</p:dialog>
<p:commandButton id="dlgOK" value="OK"
oncomplete="PF('dlgOkRecat').hide()"
action="#{shoppingListBean.doChangeShopcat}"
update="@form:@parent:frmIsk:ctlScSel @form:@parent:frmIsk:ctlIngkeySel"
immediate="true"
/>
<p:commandButton id="dlgCancel" value="Cancel"
onclick="PF('dlgOkRecat').hide()"
/>
</p:confirmDialog>
</h:form>
</html>

View File

@ -21,3 +21,9 @@ textarea {
font-family: 'latoregular', 'Trebuchet MS,Arial,Helvetica,sans-serif';
font-size: 1em
}
#footer {
position: absolute;
bottom: 90px;
width: 100%;
}

View File

@ -25,11 +25,20 @@
}
</style>
<h:messages />
<h:form id="form1">
<p:dataTable id="tblRecipes" style="width: 600px"
value="#{shoppingListBean.recipeList}" var="item"
<p:tabView id="tabGroupClient" orientation="left"
dynamic="true"
>
<p:column headerText="Recipe">
<p:tab id="overviewTab" title="Shopping List">
<h:form id="form1">
<p:dataTable id="tblRecipes"
style="width: 600px"
value="#{shoppingListBean.recipeList}"
var="item"
>
<f:facet name="header">
<h:outputText value="Recipes" />
</f:facet>
<p:column>
<h:outputText value="#{item.title}" />
</p:column>
</p:dataTable>
@ -43,17 +52,22 @@
sortBy="#{item.shopCat}" var="item"
>
<f:facet name="header">
<h:outputText styleClass="subtitle"
<h:outputText
styleClass="subtitle"
value="Ingredients"
/>
</f:facet>
<p:headerRow>
<p:column colspan="4">
<h:outputText value="#{item.shopCat}" />
<h:outputText
value="#{item.shopCat}"
/>
</p:column>
</p:headerRow>
<p:column label="ingKey">
<h:outputText value="#{item.ingkey}" />
<h:outputText
value="#{item.ingkey}"
/>
</p:column>
<p:column label="Amt"
style="width: 3em; text-align: right"
@ -62,20 +76,36 @@
value="#{item.displayAmount}"
/>
</p:column>
<p:column label="Units" style="width: 5em">
<h:outputText value="#{item.unit}" />
<p:column label="Units"
style="width: 5em"
>
<h:outputText
value="#{item.unit}"
/>
</p:column>
<p:column label="Item" style="width: 20em">
<h:outputText value="#{item.item}" />
<p:column label="Item"
style="width: 20em"
>
<h:outputText
value="#{item.item}"
/>
</p:column>
</p:dataTable>
</p:column>
</h:form>
</p:tab>
<!-- -->
<p:tab id="ingshopcatEditTab" title="Edit">
<ui:include
src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"
/>
</p:tab>
</p:tabView>
<h:form id="frmHome">
<p:commandButton id="doHome" value="Home"
icon="ui-icon-home" ajax="false" immediate="true"
action="main.jsf"
/>
</h:form>
<!-- -->
<ui:include src="/WEB-INF/layout/misctabs/ingshopkey.xhtml"/>
</ui:define>
</ui:composition>