Close to the same feature set as the Go interface
Some checks failed
Build / build (push) Failing after 19s
Some checks failed
Build / build (push) Failing after 19s
This commit is contained in:
@@ -24,7 +24,10 @@ public class WebController {
|
||||
private static final String DESCRIPTORS = "descriptors";
|
||||
/// The name of the model attribute that holds the asset descriptor for the current view.
|
||||
private static final String DESCRIPTOR = "descriptor";
|
||||
private static final String GENERIC_DESCRIPTOR = "generic";
|
||||
/// The name of the model attribute that holds the list of assets.
|
||||
private static final String ASSETS = "assets";
|
||||
/// The name of the model attribute that holds a list of all properties of all descriptors.
|
||||
private static final String PROPERTIES = "properties";
|
||||
|
||||
private final AssetService assetService;
|
||||
|
||||
@@ -38,6 +41,33 @@ public class WebController {
|
||||
return "index";
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows a view where a user can select the type of asset to browse.
|
||||
*/
|
||||
@GetMapping("/browse")
|
||||
public String browse(Model model) {
|
||||
model.addAttribute(DESCRIPTORS, assetService.getAssetDescriptors());
|
||||
return "browse";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the browsing of assets by type.
|
||||
* Displays the asset descriptor tree and the specific descriptor for the given type.
|
||||
*
|
||||
* @param model The model to add attributes to.
|
||||
* @param type The type of asset to browse.
|
||||
* @return The view name for browsing assets by type.
|
||||
*/
|
||||
@GetMapping("/browse/{type}")
|
||||
public String browseType(Model model, @PathVariable String type) {
|
||||
var tree = assetService.getAssetDescriptorTree(type);
|
||||
model.addAttribute(DESCRIPTOR, assetService.getAssetDescriptor(type));
|
||||
model.addAttribute(DESCRIPTORS, tree);
|
||||
model.addAttribute(PROPERTIES, tree.stream().flatMap(d -> d.getProperties().stream()).toList());
|
||||
model.addAttribute(ASSETS, assetService.getAssetsByType(type));
|
||||
return "browse_type";
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the view of an asset by its QR code.
|
||||
* If the asset does not exist, it redirects to the index page.
|
||||
|
||||
@@ -19,9 +19,12 @@ public class AssetDescriptor {
|
||||
/// The type of property, e.g.: ram, asset, etc...
|
||||
private final String type;
|
||||
|
||||
/// The displayable name of the property, e.g.: "Random Access memory"
|
||||
/// The displayable name of the property, e.g.: "Random Access Memory"
|
||||
private final String displayName;
|
||||
|
||||
/// The plural name of the property, e.g.: "Random Access Memories"
|
||||
private final String pluralName;
|
||||
|
||||
/// Whether the asset is visible in the user interface.
|
||||
private final boolean visible;
|
||||
|
||||
@@ -44,6 +47,7 @@ public class AssetDescriptor {
|
||||
var builder = AssetDescriptor.builder()
|
||||
.type(assetInfo.type())
|
||||
.displayName(assetInfo.displayName())
|
||||
.pluralName(assetInfo.pluralName())
|
||||
.visible(assetInfo.isVisible())
|
||||
.properties(Arrays.stream(assetType.getDeclaredFields())
|
||||
.map(field -> AssetProperty.loadFrom(field, assetInfo.type()))
|
||||
|
||||
@@ -16,14 +16,21 @@ public @interface AssetInfo {
|
||||
*
|
||||
* @return the display name of the asset type
|
||||
*/
|
||||
String displayName() default "";
|
||||
String displayName();
|
||||
|
||||
/**
|
||||
* The plural name of the asset type, used for display purposes.
|
||||
*
|
||||
* @return the plural name of the asset type
|
||||
*/
|
||||
String pluralName();
|
||||
|
||||
/**
|
||||
* The type of the asset, which can be a string or an integer.
|
||||
*
|
||||
* @return the type of the asset
|
||||
*/
|
||||
String type() default "";
|
||||
String type();
|
||||
|
||||
/**
|
||||
* Indicates whether the asset type should be visible in the UI.
|
||||
|
||||
@@ -17,6 +17,7 @@ import lombok.Setter;
|
||||
@Entity
|
||||
@AssetInfo(
|
||||
displayName = "Asset",
|
||||
pluralName = "Assets",
|
||||
type = "asset",
|
||||
isVisible = false
|
||||
)
|
||||
|
||||
@@ -15,6 +15,7 @@ import lombok.Setter;
|
||||
@Entity
|
||||
@AssetInfo(
|
||||
displayName = "Hard Drive",
|
||||
pluralName = "Hard Drives",
|
||||
type = "HDD"
|
||||
)
|
||||
@Table(name = "hdd_assets")
|
||||
|
||||
@@ -15,6 +15,7 @@ import lombok.Setter;
|
||||
@Entity
|
||||
@AssetInfo(
|
||||
displayName = "Random Access Memory",
|
||||
pluralName = "Random Access Memories",
|
||||
type = "RAM"
|
||||
)
|
||||
@Table(name = "ram_assets")
|
||||
|
||||
@@ -4,6 +4,8 @@ import be.seeseepuff.pcinv.models.Asset;
|
||||
import be.seeseepuff.pcinv.models.GenericAsset;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Repository
|
||||
public interface AssetRepository<T extends Asset> {
|
||||
T saveAndFlush(T entity);
|
||||
@@ -19,6 +21,8 @@ public interface AssetRepository<T extends Asset> {
|
||||
|
||||
T findByAsset(GenericAsset asset);
|
||||
|
||||
List<T> findAll();
|
||||
|
||||
Class<T> getAssetType();
|
||||
|
||||
long count();
|
||||
|
||||
@@ -50,6 +50,16 @@ public class AssetService {
|
||||
return getRepositoryFor(genericAsset.getType()).findByAsset(genericAsset);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all assets of a specific type.
|
||||
*
|
||||
* @param type the type of asset to retrieve
|
||||
* @return a list of assets of the specified type
|
||||
*/
|
||||
public List<? extends Asset> getAssetsByType(String type) {
|
||||
return getRepositoryFor(type).findAll();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the global asset descriptors for all asset types.
|
||||
*
|
||||
|
||||
10
src/main/resources/templates/browse.html
Normal file
10
src/main/resources/templates/browse.html
Normal file
@@ -0,0 +1,10 @@
|
||||
<body th:replace="~{fragments :: base(title='Browse assets', content=~{::content})}">
|
||||
<div th:fragment="content">
|
||||
View device details
|
||||
<ul>
|
||||
<li th:each="d : ${descriptors.getAssets()}" th:if="${d.visible}">
|
||||
<a th:href="'/browse/'+${d.getType()}" th:text="${d.pluralName}"></a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</body>
|
||||
13
src/main/resources/templates/browse_type.html
Normal file
13
src/main/resources/templates/browse_type.html
Normal file
@@ -0,0 +1,13 @@
|
||||
<body th:replace="~{fragments :: base(title='View '+${descriptor.pluralName}, content=~{::content})}">
|
||||
<div th:fragment="content">
|
||||
There are <span th:text="${assets.size()}"></span> <span th:text="${descriptor.pluralName}"></span> in the database.
|
||||
<table border="1">
|
||||
<tr>
|
||||
<th th:each="p : ${properties}" th:text="${p.displayName}" bgcolor="#d3d3d3"></th>
|
||||
</tr>
|
||||
<tr th:each="a : ${assets}">
|
||||
<td th:each="p : ${properties}"><a th:href="'/view/'+${a.getQr()}" th:text="${p.renderValue(a)}"></a></td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
</body>
|
||||
@@ -1,4 +1,4 @@
|
||||
<body th:replace="~{fragments :: base(title='Select type to create', content=~{::content})}">
|
||||
<body th:replace="~{fragments :: base(title='Create '+${descriptor.displayName}, content=~{::content})}">
|
||||
<div th:fragment="content">
|
||||
Create a <span th:text="${descriptor.displayName}"></span>
|
||||
<form th:action="'/create/'+${descriptor.getType()}" method="post">
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
<body th:replace="~{fragments :: base(title='Select type to create', content=~{::content})}">
|
||||
<body th:replace="~{fragments :: base(title='View asset information', content=~{::content})}">
|
||||
<div th:fragment="content">
|
||||
View device details
|
||||
<div th:each="d : ${descriptors}">
|
||||
|
||||
Reference in New Issue
Block a user