Shopcat in progress (doSave)

This commit is contained in:
Tim Holloway 2022-01-03 16:48:15 -05:00
parent 735bf814cf
commit a86f45e4c4
10 changed files with 121 additions and 73 deletions

View File

@ -123,6 +123,7 @@ public class AdminMainBean implements Serializable {
*/ */
@PostConstruct @PostConstruct
void init() { void init() {
log.info("Constructing AdminMainBean " + this);
this.setSearchText(userSession.getLastSearch()); this.setSearchText(userSession.getLastSearch());
// Clean up from any previous operations. // Clean up from any previous operations.
this.userSession.setRecipe(null); this.userSession.setRecipe(null);
@ -191,6 +192,7 @@ public class AdminMainBean implements Serializable {
/** /**
* Get printable preptime. Database version is in seconds. * Get printable preptime. Database version is in seconds.
* @deprecated User {@link UserSession#formatTime(Long)}
* *
* @return Formatted time. Called from EL on main page. * @return Formatted time. Called from EL on main page.
*/ */
@ -210,17 +212,4 @@ public class AdminMainBean implements Serializable {
return sb.toString(); return sb.toString();
} }
public String formatCategories(Recipe r) {
StringBuffer sb = new StringBuffer(30);
boolean first = true;
for (Category cat : r.getCategories()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(cat.getCategory());
}
return sb.toString();
}
} }

View File

@ -218,6 +218,8 @@ public class RecipeDetailBean implements Serializable {
private void init() { private void init() {
this.recipe = userSession.getRecipe(); this.recipe = userSession.getRecipe();
log.info("Using recipe: " + this.recipe );
/** /**
* For "create new, this recipe is a blank constructed * For "create new, this recipe is a blank constructed
* and passed from main page. For Detail display, it's * and passed from main page. For Detail display, it's
@ -241,6 +243,7 @@ public class RecipeDetailBean implements Serializable {
getIngredients().setWrappedData( getIngredients().setWrappedData(
buildIngredientFacade(recipe.getIngredientHash())); buildIngredientFacade(recipe.getIngredientHash()));
log.info("Set recipe: " + this.recipe );
} }
/** /**
@ -367,8 +370,8 @@ public class RecipeDetailBean implements Serializable {
* *
* Note: In the original Tobago port of this app, the input * Note: In the original Tobago port of this app, the input
* was an inputText. In PrimeFaces, this did not preserve * was an inputText. In PrimeFaces, this did not preserve
* line separation characters, so an inputTextArea was * line separation characters, so an inputTextArea was used
* used instead. * instead.
* *
* @param event Unused * @param event Unused
*/ */
@ -450,7 +453,8 @@ public class RecipeDetailBean implements Serializable {
} }
// Otherwise, try for split. // Otherwise, try for split.
String[] lineArray = ingredientTextLines.split(RE_INGSPLIT); String[] lineArray =
ingredientTextLines.split(RE_INGSPLIT);
for (String line : lineArray) { for (String line : lineArray) {
if (line.isBlank()) { if (line.isBlank()) {
continue; // actually should discard any above continue; // actually should discard any above
@ -538,16 +542,22 @@ public class RecipeDetailBean implements Serializable {
* save ingredients. * save ingredients.
*/ */
public String doSave() { public String doSave() {
// if ! isDirty()...
// Update recipe object based on UI:
if (!saveIngredients()) { if (!saveIngredients()) {
JSFUtils
.addErrorMessage("Could not save Ingredients");
return null;
}
if (recipeService.save(this.getRecipe())) {
userSession.setRecipe(null);
return "main";
} else {
JSFUtils.addErrorMessage("Save recipe failed");
return null; return null;
} }
updateRecipeCategories(recipe, category);
// Rebuild ingredients list with groups applied
updateRecipeGroups(getWrappedIngredients());
recipeService.save(recipe);
userSession.setRecipe(null);
setDirty(false);
return "main";
} }
/** /**
@ -587,6 +597,16 @@ public class RecipeDetailBean implements Serializable {
* it. * it.
*/ */
private boolean saveIngredients() { private boolean saveIngredients() {
if ( ! updateIngredientList()) {
return false;
}
updateRecipeCategories(recipe, category);
// Rebuild ingredients list with groups applied
updateRecipeGroups(getWrappedIngredients());
return true;
}
private boolean updateIngredientList() {
List<IngredientUI> saveIng = getWrappedIngredients(); List<IngredientUI> saveIng = getWrappedIngredients();
List<Ingredient> iList = recipe.getIngredientHash(); List<Ingredient> iList = recipe.getIngredientHash();
iList.clear(); iList.clear();
@ -599,7 +619,7 @@ public class RecipeDetailBean implements Serializable {
if (scat == null) { if (scat == null) {
if ((ingKey != null) && !ingKey.isBlank()) { if ((ingKey != null) && !ingKey.isBlank()) {
scat = new Shopcat(); scat = new Shopcat();
scat.setIngkey(ingKey); // scat.setIngkey(ingKey);
scat.setShopcategory(shopCatName); scat.setShopcategory(shopCatName);
ing.setShopCat(scat); ing.setShopCat(scat);
} else { } else {
@ -766,7 +786,7 @@ public class RecipeDetailBean implements Serializable {
this.cuisineList = cuisineList; this.cuisineList = cuisineList;
} }
//*** // ***
// Shopcat for IngredientUI // Shopcat for IngredientUI
private List<String> shopcatList; private List<String> shopcatList;
@ -889,11 +909,12 @@ public class RecipeDetailBean implements Serializable {
* *
* @param event PrimeFaces file upload event object * @param event PrimeFaces file upload event object
*/ */
public void ajaxUploadImage(FileUploadEvent event) { public void ajaxUploadImage(FileUploadEvent event) {
UploadedFile foo = event.getFile(); UploadedFile foo = event.getFile();
PictureController.importImage(recipe, foo.getContents()); PictureController.importImage(recipe, foo.getContents());
} }
/** /**
* Remove images from recipe * Remove images from recipe
* *

View File

@ -5,6 +5,7 @@ import java.io.Serializable;
import javax.enterprise.context.SessionScoped; import javax.enterprise.context.SessionScoped;
import javax.inject.Named; import javax.inject.Named;
import com.mousetech.gourmetj.persistence.model.Category;
import com.mousetech.gourmetj.persistence.model.Recipe; import com.mousetech.gourmetj.persistence.model.Recipe;
@Named @Named
@ -97,6 +98,21 @@ public class UserSession implements Serializable {
} }
// ==== // ====
public String formatCategories(Recipe r) {
StringBuffer sb = new StringBuffer(30);
boolean first = true;
for (Category cat : r.getCategories()) {
if (first) {
first = false;
} else {
sb.append(", ");
}
sb.append(cat.getCategory());
}
return sb.toString();
}
public String formatTime(Long ltime) { public String formatTime(Long ltime) {
if (ltime == null) { if (ltime == null) {
return ""; return "";

View File

@ -5,9 +5,10 @@ import javax.persistence.*;
import javax.validation.constraints.NotNull; import javax.validation.constraints.NotNull;
/** /**
* The persistent class for the "ingredients" database table. * The persistent class for the "ingredients" database table. The
* The display model is @see IngredientUI. Persistence * display model is @see IngredientUI. Persistence is usually
* is usually done along with the containing recipe via * done along with the containing recipe via
*
* @see RecipeService. * @see RecipeService.
*/ */
@Entity @Entity
@ -16,9 +17,12 @@ import javax.validation.constraints.NotNull;
public class Ingredient implements Serializable, IngredientIF { public class Ingredient implements Serializable, IngredientIF {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ManyToOne(fetch = FetchType.LAZY, cascade = { @ManyToOne(fetch = FetchType.EAGER, cascade = {
CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH }, optional = true) CascadeType.PERSIST, CascadeType.MERGE,
@JoinColumn(name = "ingkey",insertable = false, updatable = false, nullable = true) CascadeType.REFRESH }, optional = true)
@JoinColumn(name = "ingkey", insertable = false,
updatable = false, nullable = true,
foreignKey = @ForeignKey(name = "ingkey"))
Shopcat shopCat; Shopcat shopCat;
/** /**

View File

@ -1,8 +1,20 @@
package com.mousetech.gourmetj.persistence.model; package com.mousetech.gourmetj.persistence.model;
import java.io.Serializable; import java.io.Serializable;
import javax.persistence.*; import java.util.ArrayList;
import javax.validation.constraints.NotNull; import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToMany;
import javax.persistence.Table;
/** /**
* The persistent class for the "shopcats" database table. * The persistent class for the "shopcats" database table.
@ -19,9 +31,6 @@ import javax.validation.constraints.NotNull;
*/ */
@Entity @Entity
@Table(name = "shopcats") @Table(name = "shopcats")
@NamedQueries({
@NamedQuery(name = "Shopcat.findAll", query = "SELECT s FROM Shopcat s"),
@NamedQuery(name = "Shopcat.findIngkey", query = "SELECT s FROM Shopcat s where s.ingkey = :ingkey") })
public class Shopcat implements Serializable { public class Shopcat implements Serializable {
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
@ -30,11 +39,23 @@ public class Shopcat implements Serializable {
@Column(name = "id") @Column(name = "id")
private Long id; private Long id;
@Column(name = "ingkey") //@Column(name = "ingkey", unique = true, nullable = false )
@NotNull @OneToMany(fetch = FetchType.LAZY, mappedBy = "ingkey" )
// @UniqueConstraint(name="ingkey") private List<Ingredient> ingredients;
private String ingkey;
// @OneToMany ingredients /**
* @return the ingredients
*/
public List<Ingredient> getIngredients() {
return ingredients;
}
/**
* @param ingredients the ingredients to set
*/
public void setIngredients(List<Ingredient> ingredient) {
this.ingredients = ingredient;
}
@Column(name = "position") @Column(name = "position")
private Integer position; private Integer position;
@ -53,14 +74,6 @@ public class Shopcat implements Serializable {
this.id = id; this.id = id;
} }
public String getIngkey() {
return this.ingkey;
}
public void setIngkey(String ingkey) {
this.ingkey = ingkey;
}
public Integer getPosition() { public Integer getPosition() {
return this.position; return this.position;
} }
@ -79,7 +92,7 @@ public class Shopcat implements Serializable {
@Override @Override
public String toString() { public String toString() {
return "Shopcat for " + ingkey + "(" + shopcategory return "Shopcat for " + "(" + shopcategory
+ ")"; + ")";
} }
} }

View File

@ -66,9 +66,9 @@ public class RecipeService implements Serializable {
return recipeRepository.FindCuisinesNative(); return recipeRepository.FindCuisinesNative();
} }
public void save(Recipe recipe) { public boolean save(Recipe recipe) {
// TODO Auto-generated method stub recipeRepository.save(recipe);
return true;
} }
public void delete(Recipe recipe) { public void delete(Recipe recipe) {

View File

@ -143,7 +143,12 @@ public class PictureController {
httpHeaders.set(HttpHeaders.CONTENT_TYPE, httpHeaders.set(HttpHeaders.CONTENT_TYPE,
MediaType.IMAGE_PNG_VALUE); MediaType.IMAGE_PNG_VALUE);
httpHeaders.set(HttpHeaders.CACHE_CONTROL, "no-cache"); httpHeaders.set(HttpHeaders.CACHE_CONTROL, "no-cache");
byte[] image = editRecipe.getImage(); byte[] image = null;
if ( editRecipe != null ) {
// Otherwise we are creating new recipe, pre-display
image = editRecipe.getImage();
}
if (image == null) { if (image == null) {
image = BLANK_IMAGE; image = BLANK_IMAGE;
} }

View File

@ -8,7 +8,7 @@
> >
<ui:define name="title">Gourmet Recipe Manager</ui:define> <ui:define name="title">Gourmet Recipe Manager</ui:define>
<ui:define name="content"> <ui:define name="content">
<style> <style>
.ingSel { .ingSel {
width: 3em; width: 3em;
text-align: center; text-align: center;
@ -132,8 +132,7 @@
title="Ingredients" title="Ingredients"
> >
<p:panel id="pnlIngredients"> <p:panel id="pnlIngredients">
<f:facet name="header">Ingredients</f:facet> <f:facet name="header">Ingredients</f:facet>
<!-- NOTE: disabled doesn't work from AJAX render. Swap images -->
<h:panelGroup id="ingButtons"> <h:panelGroup id="ingButtons">
<p:commandButton value="Up" <p:commandButton value="Up"
id="ctlUp" id="ctlUp"
@ -281,15 +280,16 @@
</p:dataTable> </p:dataTable>
</h:panelGrid> </h:panelGrid>
<h:panelGroup id="pnlIng"> <h:panelGroup id="pnlIng">
<p:remoteCommand name="ingButton" <p:remoteCommand name="ingButton"
action="#{recipeDetailBean.doAddIngredient}" action="#{recipeDetailBean.doAddIngredient}"
process="@this ctlAddIngTxt" process="@this ctlAddIngTxt"
update="pnlIngredients" update="pnlIngredients"
/> />
<p:outputLabel for="@next" <p:outputLabel for="@next"
value="Add Ingredient: " value="Add Ingredient: "
/> />
<p:inputTextarea id="ctlAddIngTxt" <p:inputTextarea
id="ctlAddIngTxt"
focus="true" rows="1" focus="true" rows="1"
cols="65" cols="65"
value="#{recipeDetailBean.ingredientText}" value="#{recipeDetailBean.ingredientText}"
@ -326,8 +326,8 @@
</p:panel> </p:panel>
</p:tab> </p:tab>
</p:tabView> </p:tabView>
<p:button id="doSave" value="Save" <p:commandButton id="doSave" value="Save"
disabled="{recipeDetailBean.dirty}" disabled="{not recipeDetailBean.dirty}"
action="#{recipeDetailBean.doSave}" action="#{recipeDetailBean.doSave}"
/> />
<p:commandButton id="doCancel" value="Cancel" <p:commandButton id="doCancel" value="Cancel"

View File

@ -57,7 +57,7 @@
</p:column> </p:column>
<p:column headerText="Category"> <p:column headerText="Category">
<h:outputText <h:outputText
value="#{adminMainBean.formatCategories(row)}" value="#{userSession.formatCategories(row)}"
/> />
</p:column> </p:column>
<p:column headerText="Cuisine"> <p:column headerText="Cuisine">
@ -73,7 +73,7 @@
</p:column> </p:column>
<p:column headerText="Prep Time"> <p:column headerText="Prep Time">
<h:outputText <h:outputText
value="#{adminMainBean.formatPreptime(row.preptime)}" value="#{userSession.formatTime(row.preptime)}"
/> />
</p:column> </p:column>
</p:dataTable> </p:dataTable>

View File

@ -61,7 +61,7 @@
/> />
<h:outputText <h:outputText
label="Category: " label="Category: "
value="#{adminMainBean.formatCategories(recipeDetailBean.recipe)}" value="#{userSession.formatCategories(recipeDetailBean.recipe)}"
/> />
<p:outputLabel for="@next" <p:outputLabel for="@next"
value="Cuisine:" value="Cuisine:"