Skip to content
Snippets Groups Projects
Commit 00a25e55 authored by Robert Goldmann's avatar Robert Goldmann
Browse files

#419 - new database entity for images

parent 20be3370
Branches
Tags
No related merge requests found
package de.deadlocker8.budgetmaster.accounts; package de.deadlocker8.budgetmaster.accounts;
import com.google.gson.annotations.Expose; import com.google.gson.annotations.Expose;
import de.deadlocker8.budgetmaster.images.Image;
import de.deadlocker8.budgetmaster.transactions.Transaction; import de.deadlocker8.budgetmaster.transactions.Transaction;
import javax.persistence.*; import javax.persistence.*;
...@@ -30,20 +31,21 @@ public class Account ...@@ -30,20 +31,21 @@ public class Account
private Boolean isDefault = false; private Boolean isDefault = false;
private Boolean isReadOnly = false; private Boolean isReadOnly = false;
@ManyToOne
@Expose @Expose
private String iconPath; private Image icon;
@Expose @Expose
private AccountType type; private AccountType type;
public Account(String name, AccountType type, String iconPath) public Account(String name, AccountType type, Image icon)
{ {
this.name = name; this.name = name;
this.type = type; this.type = type;
this.isSelected = false; this.isSelected = false;
this.isDefault = false; this.isDefault = false;
this.isReadOnly = false; this.isReadOnly = false;
this.iconPath = iconPath; this.icon = icon;
} }
public Account(String name, AccountType type) public Account(String name, AccountType type)
...@@ -125,14 +127,14 @@ public class Account ...@@ -125,14 +127,14 @@ public class Account
this.type = type; this.type = type;
} }
public String getIconPath() public Image getIcon()
{ {
return iconPath; return icon;
} }
public void setIconPath(String iconPath) public void setIcon(Image icon)
{ {
this.iconPath = iconPath; this.icon = icon;
} }
@Override @Override
...@@ -146,7 +148,7 @@ public class Account ...@@ -146,7 +148,7 @@ public class Account
", isDefault=" + isDefault + ", isDefault=" + isDefault +
", isReadOnly=" + isReadOnly + ", isReadOnly=" + isReadOnly +
", type=" + type + ", type=" + type +
", iconPath=" + iconPath + ", icon=" + icon +
'}'; '}';
} }
...@@ -162,12 +164,12 @@ public class Account ...@@ -162,12 +164,12 @@ public class Account
Objects.equals(ID, account.ID) && Objects.equals(ID, account.ID) &&
Objects.equals(name, account.name) && Objects.equals(name, account.name) &&
type == account.type && type == account.type &&
Objects.equals(iconPath, account.iconPath); Objects.equals(icon, account.icon);
} }
@Override @Override
public int hashCode() public int hashCode()
{ {
return Objects.hash(ID, name, isSelected, isDefault, isReadOnly, type, iconPath); return Objects.hash(ID, name, isSelected, isDefault, isReadOnly, type, icon);
} }
} }
\ No newline at end of file
package de.deadlocker8.budgetmaster.accounts; package de.deadlocker8.budgetmaster.accounts;
import de.deadlocker8.budgetmaster.controller.BaseController; import de.deadlocker8.budgetmaster.controller.BaseController;
import de.deadlocker8.budgetmaster.images.ImageService;
import de.deadlocker8.budgetmaster.settings.SettingsService; import de.deadlocker8.budgetmaster.settings.SettingsService;
import de.deadlocker8.budgetmaster.utils.Mappings; import de.deadlocker8.budgetmaster.utils.Mappings;
import de.deadlocker8.budgetmaster.utils.ResourceNotFoundException; import de.deadlocker8.budgetmaster.utils.ResourceNotFoundException;
...@@ -27,12 +28,14 @@ public class AccountController extends BaseController ...@@ -27,12 +28,14 @@ public class AccountController extends BaseController
{ {
private final AccountService accountService; private final AccountService accountService;
private final SettingsService settingsService; private final SettingsService settingsService;
private final ImageService imageService;
@Autowired @Autowired
public AccountController(AccountService accountService, SettingsService settingsService) public AccountController(AccountService accountService, SettingsService settingsService, ImageService imageService)
{ {
this.accountService = accountService; this.accountService = accountService;
this.settingsService = settingsService; this.settingsService = settingsService;
this.imageService = imageService;
} }
@GetMapping(value = "/{ID}/select") @GetMapping(value = "/{ID}/select")
...@@ -129,7 +132,7 @@ public class AccountController extends BaseController ...@@ -129,7 +132,7 @@ public class AccountController extends BaseController
Account emptyAccount = new Account(); Account emptyAccount = new Account();
model.addAttribute("account", emptyAccount); model.addAttribute("account", emptyAccount);
model.addAttribute("settings", settingsService.getSettings()); model.addAttribute("settings", settingsService.getSettings());
model.addAttribute("iconImages", List.of("https://localhost:9000/touch_icon.png", "https://localhost:9000/touch_icon.png")); model.addAttribute("availableImages", imageService.getRepository().findAll());
return "accounts/newAccount"; return "accounts/newAccount";
} }
...@@ -144,7 +147,7 @@ public class AccountController extends BaseController ...@@ -144,7 +147,7 @@ public class AccountController extends BaseController
model.addAttribute("account", accountOptional.get()); model.addAttribute("account", accountOptional.get());
model.addAttribute("settings", settingsService.getSettings()); model.addAttribute("settings", settingsService.getSettings());
model.addAttribute("iconImages", List.of("https://localhost:9000/touch_icon.png", "https://localhost:9000/touch_icon.png")); model.addAttribute("availableImages", imageService.getRepository().findAll());
return "accounts/newAccount"; return "accounts/newAccount";
} }
...@@ -168,7 +171,7 @@ public class AccountController extends BaseController ...@@ -168,7 +171,7 @@ public class AccountController extends BaseController
model.addAttribute("error", bindingResult); model.addAttribute("error", bindingResult);
model.addAttribute("account", account); model.addAttribute("account", account);
model.addAttribute("settings", settingsService.getSettings()); model.addAttribute("settings", settingsService.getSettings());
model.addAttribute("iconImages", List.of("https://localhost:9000/touch_icon.png", "https://localhost:9000/touch_icon.png")); model.addAttribute("availableImages", imageService.getRepository().findAll());
return "accounts/newAccount"; return "accounts/newAccount";
} }
else else
...@@ -187,7 +190,7 @@ public class AccountController extends BaseController ...@@ -187,7 +190,7 @@ public class AccountController extends BaseController
{ {
Account existingAccount = existingAccountOptional.get(); Account existingAccount = existingAccountOptional.get();
existingAccount.setName(account.getName()); existingAccount.setName(account.getName());
existingAccount.setIconPath(account.getIconPath()); existingAccount.setIcon(account.getIcon());
accountService.getRepository().save(existingAccount); accountService.getRepository().save(existingAccount);
} }
} }
......
package de.deadlocker8.budgetmaster.images;
import com.google.gson.annotations.Expose;
import de.deadlocker8.budgetmaster.accounts.Account;
import javax.persistence.*;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;
import java.util.List;
import java.util.Objects;
@Entity
public class Image
{
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Expose
private Integer ID;
@NotNull
@Size(min = 1)
@Expose
private String imagePath;
@OneToMany(mappedBy = "icon", fetch = FetchType.LAZY)
private List<Account> referringAccounts;
public Image(String imagePath)
{
this.imagePath = imagePath;
}
public Image()
{
}
public Integer getID()
{
return ID;
}
public void setID(Integer ID)
{
this.ID = ID;
}
public String getImagePath()
{
return imagePath;
}
public void setImagePath(String imagePath)
{
this.imagePath = imagePath;
}
public List<Account> getReferringAccounts()
{
return referringAccounts;
}
@Override
public String toString()
{
return "Image{" +
"ID=" + ID +
", imagePath='" + imagePath + '\'' +
'}';
}
@Override
public boolean equals(Object o)
{
if(this == o) return true;
if(o == null || getClass() != o.getClass()) return false;
Image image = (Image) o;
return Objects.equals(ID, image.ID) && Objects.equals(imagePath, image.imagePath);
}
@Override
public int hashCode()
{
return Objects.hash(ID, imagePath);
}
}
\ No newline at end of file
package de.deadlocker8.budgetmaster.images;
import org.springframework.data.jpa.repository.JpaRepository;
public interface ImageRepository extends JpaRepository<Image, Integer>
{
}
\ No newline at end of file
package de.deadlocker8.budgetmaster.images;
import de.deadlocker8.budgetmaster.services.Resetable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ImageService implements Resetable
{
private static final Logger LOGGER = LoggerFactory.getLogger(ImageService.class);
private final ImageRepository imageRepository;
@Autowired
public ImageService(ImageRepository imageRepository)
{
this.imageRepository = imageRepository;
}
public ImageRepository getRepository()
{
return imageRepository;
}
@Override
public void deleteAll()
{
// TODO: set placeholder image for all accounts
imageRepository.deleteAll();
}
@Override
public void createDefaults()
{
if(imageRepository.findAll().isEmpty())
{
// TODO: insert placeholder image
// Account placeholder = new Account("Placeholder", AccountType.ALL);
// accountRepository.save(placeholder);
// LOGGER.debug("Created placeholder account");
//
// Account account = accountRepository.save(new Account(Localization.getString(Strings.ACCOUNT_DEFAULT_NAME), AccountType.CUSTOM));
// selectAccount(account.getID());
// setAsDefaultAccount(account.getID());
// LOGGER.debug("Created default account");
}
}
}
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
<div id="modalAccountIconSelect" class="modal modal-fixed-footer background-color"> <div id="modalAccountIconSelect" class="modal modal-fixed-footer background-color">
<div class="modal-content"> <div class="modal-content">
<div class="row"> <div class="row">
<#list iconImages as image> <#list availableImages as image>
<@accountIconOption image/> <@accountIconOption image/>
</#list> </#list>
</div> </div>
...@@ -16,10 +16,10 @@ ...@@ -16,10 +16,10 @@
</div> </div>
</#macro> </#macro>
<#macro accountIconOption icon> <#macro accountIconOption image>
<div class="col s4 m2 l2 account-icon-option-column"> <div class="col s4 m2 l2 account-icon-option-column">
<div class="account-icon-option"> <div class="account-icon-option">
<img src="${icon}" class="account-icon-preview" alt="${icon}" data-image-id="1"/> <img src="${image.getImagePath()}" class="account-icon-preview" alt="${image.getImagePath()}" data-image-id="${image.getID()}"/>
</div> </div>
</div> </div>
</#macro> </#macro>
\ No newline at end of file
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
<a href="<@s.url '/accounts/${account.getID()?c}/toggleReadOnly'/>" class="btn-flat no-padding text-default tooltipped" data-position="right" data-tooltip="${toolTipText}">${lockIcon}</a> <a href="<@s.url '/accounts/${account.getID()?c}/toggleReadOnly'/>" class="btn-flat no-padding text-default tooltipped" data-position="right" data-tooltip="${toolTipText}">${lockIcon}</a>
</#if> </#if>
</td> </td>
<td><#if account.getIconPath()?has_content><img src="${account.getIconPath()}" class="account-icon"/></#if></td> <td><#if account.getIcon()??><img src="${account.getIcon().getImagePath()}" class="account-icon"/></#if></td>
<td>${account.getName()}</td> <td>${account.getName()}</td>
<td> <td>
<a href="<@s.url '/accounts/${account.getID()?c}/edit'/>" class="btn-flat no-padding text-default"><i class="material-icons left">edit</i></a> <a href="<@s.url '/accounts/${account.getID()?c}/edit'/>" class="btn-flat no-padding text-default"><i class="material-icons left">edit</i></a>
......
...@@ -54,11 +54,12 @@ ...@@ -54,11 +54,12 @@
<div id="account-icon" class="valign-wrapper"> <div id="account-icon" class="valign-wrapper">
<a href="#modalAccountIconSelect" id="account-icon-preview" class="modal-trigger"> <a href="#modalAccountIconSelect" id="account-icon-preview" class="modal-trigger">
<img id="account-icon-preview-icon" src="<#if account.getIconPath()?has_content>${account.getIconPath()}</#if>" class="account-icon-preview <#if account.getIconPath()?has_content == false>hidden</#if>"/> <img id="account-icon-preview-icon" src="<#if account.getIcon()??>${account.getIcon().getImagePath()}</#if>" class="account-icon-preview <#if account.getIcon()?? == false>hidden</#if>"/>
<div id="account-icon-placeholder" class="<#if account.getIconPath()?has_content>hidden</#if>">${locale.getString("account.new.icon.placeholder")}</div> <div id="account-icon-placeholder" class="<#if account.getIcon()??>hidden</#if>">${locale.getString("account.new.icon.placeholder")}</div>
</a> </a>
<@header.buttonFlat url='' icon='delete' id='button-remove-account-icon' localizationKey='' classes="no-padding text-default" noUrl=true/> <@header.buttonFlat url='' icon='delete' id='button-remove-account-icon' localizationKey='' classes="no-padding text-default" noUrl=true/>
<input id="hidden-input-account-icon" type="hidden" name="iconPath" value="<#if account.getIconPath()??>${account.getIconPath()}</#if>">
<input id="hidden-input-account-icon" type="hidden" name="icon" value="<#if account.getIcon()??>${account.getIcon().getID()?c}</#if>">
</div> </div>
</div> </div>
</div> </div>
......
...@@ -8,6 +8,7 @@ import de.deadlocker8.budgetmaster.charts.Chart; ...@@ -8,6 +8,7 @@ import de.deadlocker8.budgetmaster.charts.Chart;
import de.deadlocker8.budgetmaster.charts.ChartType; import de.deadlocker8.budgetmaster.charts.ChartType;
import de.deadlocker8.budgetmaster.database.Database; import de.deadlocker8.budgetmaster.database.Database;
import de.deadlocker8.budgetmaster.database.DatabaseParser_v5; import de.deadlocker8.budgetmaster.database.DatabaseParser_v5;
import de.deadlocker8.budgetmaster.images.Image;
import de.thecodelabs.utils.util.Localization; import de.thecodelabs.utils.util.Localization;
import de.thecodelabs.utils.util.Localization.LocalizationDelegate; import de.thecodelabs.utils.util.Localization.LocalizationDelegate;
import org.junit.Before; import org.junit.Before;
...@@ -95,7 +96,8 @@ public class DatabaseParser_v5Test ...@@ -95,7 +96,8 @@ public class DatabaseParser_v5Test
DatabaseParser_v5 importer = new DatabaseParser_v5(json); DatabaseParser_v5 importer = new DatabaseParser_v5(json);
Database database = importer.parseDatabaseFromJSON(); Database database = importer.parseDatabaseFromJSON();
final Account account = new Account("Second Account", AccountType.CUSTOM, "myPath/to/fancy/icon.png"); // TODO
final Account account = new Account("Second Account", AccountType.CUSTOM, new Image());
account.setID(3); account.setID(3);
assertThat(database.getAccounts()).hasSize(3) assertThat(database.getAccounts()).hasSize(3)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment