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 javax.inject.Named;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.ReorderEvent;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 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) { if (shopcatList == null) {
shopcatList = loadShopcatList(); shopcatList = loadShopcatList();
} }
@ -163,9 +162,9 @@ public class ShoppingListBean implements Serializable {
@Inject @Inject
ShopcatRepository shopcatRepository; ShopcatRepository shopcatRepository;
private List<Shopcat> loadShopcatList() { private List<String> loadShopcatList() {
return shopcatRepository return shopcatRepository.findDistinctCategoryNative();
.findAllByOrderByShopcategoryAsc(); // .findAllByOrderByShopcategoryAsc();
} }
private Shopcat xeditShopcat = new Shopcat(); private Shopcat xeditShopcat = new Shopcat();
@ -180,19 +179,19 @@ public class ShoppingListBean implements Serializable {
} }
public void doEditShopcat(int scId) { public void doEditShopcat(int scId) {
xeditShopcat = null; // xeditShopcat = null;
final List<Shopcat> scl = getShopcatList(); // final List<Shopcat> scl = getShopcatList();
for (Shopcat sc : scl) { // for (Shopcat sc : scl) {
if (sc.getId() == scId) { // if (sc.getId() == scId) {
xeditShopcat = sc; // xeditShopcat = sc;
this.oldShopcategoryName = sc.getShopcategory(); // this.oldShopcategoryName = sc.getShopcategory();
if (sc.getPosition() == null) { // if (sc.getPosition() == null) {
sc.setPosition(0); // sc.setPosition(0);
} // }
return; // return;
} // }
} // }
log.error("SHOPCAT " + scId + " NOT FOUND"); // log.error("SHOPCAT " + scId + " NOT FOUND");
} }
public void ajaxOnClickShopcatIngkey() { public void ajaxOnClickShopcatIngkey() {
@ -202,12 +201,103 @@ public class ShoppingListBean implements Serializable {
} }
/** /**
* Updates all ingredient keys for shopcat name-change. * Updates all ingredient keys for shopcat name-change. Note
* Note that once done, this cannot be undone! * that once done, this cannot be undone!
*/ */
public void ajaxOnClickShopcat() { public void ajaxOnClickShopcat() {
this.shopcatRepository.UpdateShopcats( this.shopcatRepository.UpdateShopcats(
this.oldShopcategoryName, xeditShopcat.getShopcategory()); this.oldShopcategoryName,
xeditShopcat.getShopcategory());
this.shopcatList = null; 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; import com.mousetech.gourmetj.persistence.model.Shopcat;
/** /**
* JpaRepository for Shopping Categories, which relate ManyToOne to Ingredient. * JpaRepository for Shopping Categories, which relate ManyToOne
* Service method is @see RecipeService * to Ingredient. Service method is @see RecipeService
* *
* @author timh * @author timh
* @since Dec 28, 2021 * @since Dec 28, 2021
@ -34,11 +34,24 @@ public interface ShopcatRepository
@Transactional @Transactional
@Query(value = "UPDATE Shopcat set shopcategory = :newCatname WHERE shopcategory = :oldCatname") @Query(value = "UPDATE Shopcat set shopcategory = :newCatname WHERE shopcategory = :oldCatname")
@Modifying @Modifying
public int UpdateShopcats(String oldCatname, String newCatname); public int UpdateShopcats(String oldCatname,
String newCatname);
public Shopcat findShopcatByIngkey(String ingkey); public Shopcat findShopcatByIngkey(String ingkey);
public void deleteByIngkey(String key); public void deleteByIngkey(String key);
public List<Shopcat> findAllByOrderByShopcategoryAsc(); 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:insert name="content">
<ui:include src="content.xhtml" /> <ui:include src="content.xhtml" />
</ui:insert> </ui:insert>
<!-- -->
(C) 2021 Tim Holloway, Licensed under the <a <div id="footer">
href="http://www.apache.org/licenses/LICENSE-2.0" (C) 2021 Tim Holloway, Licensed under the <a
>Apache License, Version 2.0</a>. href="http://www.apache.org/licenses/LICENSE-2.0"
<p>Based on Gourmet Recipe Manager by T. Hinkle</p> >Apache License, Version 2.0</a>.
<p>Based on Gourmet Recipe Manager by T.
Hinkle</p>
</div>
<!-- -->
<h:form id="frmTimeout"> <h:form id="frmTimeout">
<p:idleMonitor <p:idleMonitor
timeout="#{userSession.sessionTimeoutInterval}" timeout="#{userSession.sessionTimeoutInterval}"

View File

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

View File

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

View File

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