Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,76 @@ These are the supported types for fields inside your `@Entity` classes (excludin

The code is still in a very early stage and it might not be robust if you use not-yet-supported JPA annotations and/or other custom configurations (e.g., custom naming strategy). If you find a bug with your settings, please report it as an issue and I will take a look at it.

## Hierarchy Tree View

SnapAdmin supports visualizing hierarchical data structures (like Brand -> Model -> Part) in an interactive tree view.

### Configuration

To enable the tree view for an entity, use the `@SnapTree` annotation.

**1. Define the Root Entity**
Annotate the root entity (e.g., `Brand`) with `@SnapTree`.

```java
@Entity
@SnapTree(
label = "Vehicle Hierarchy",
icon = "bi bi-truck",
childField = "models" // The field in this entity that points to children
)
public class Brand {
// ...
@OneToMany(mappedBy = "brand")
private Set<VehicleModel> models;
}
```

**2. Define Child Links**
Annotate the child link field in the parent entity to define the next level of hierarchy.

For example, in `VehicleModel`:

```java
@Entity
public class VehicleModel {
// ...
@ManyToMany
@SnapTree(childLabel = "Compatible Parts", icon = "bi bi-gear")
private Set<AutoPart> compatibleParts;
}
```

### Search Functionality

The tree view includes a powerful search feature that allows users to find nodes by name.
* It searches across all entities in the hierarchy.
* It automatically expands the tree to show the selected result.
* It displays the path context (e.g., `Toyota > Camry > Brake Pad`).

To customize the label shown in search results, use the `@DisplayName` annotation on a method in your entity:

```java
@Entity
public class AutoPart {
// ...
@DisplayName
public String getFullName() {
return name + " (" + partNumber + ")";
}
}
```

### Link Existing Items

For Many-to-Many relationships, you can link existing entities to a parent node directly from the tree view.
* Right-click on a node that has a Many-to-Many relationship (e.g., a `VehicleModel` with `AutoParts`).
* Select "Link Existing...".
* Search for the item you want to link.
* Select the item and click "Link".

This feature is automatically enabled for fields annotated with `@ManyToMany` where the child entity has a corresponding inverse field.

## Installation

1. SnapAdmin is distributed on Maven. For the latest stable release you can simply include the following snippet in your `pom.xml` file:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package tech.ailef.snapadmin.external.annotations;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* Annotation to define hierarchical tree structures for entities.
* Can be applied to entity classes (to mark as root) or fields (to mark as
* children).
*
* Example usage:
*
* <pre>
* {@literal @}Entity
* {@literal @}SnapTree(root = true, label = "Vehicle Hierarchy", icon = "bi bi-building")
* public class Brand {
* {@literal @}OneToMany(mappedBy = "brand")
* {@literal @}SnapTree(childLabel = "Models", icon = "bi bi-car")
* private Set&lt;VehicleModel&gt; vehicleModels;
* }
* </pre>
*/
@Target({ ElementType.TYPE, ElementType.FIELD })
@Retention(RetentionPolicy.RUNTIME)
public @interface SnapTree {
/**
* If true, marks this entity as a root node in the tree.
* Only applies to {@literal @}Entity classes.
*
* @return true if this is a root node
*/
boolean root() default false;

/**
* The label/title for this tree (only for root nodes).
* E.g., "Vehicle Hierarchy", "Part Categories"
*
* @return the tree label
*/
String label() default "";

/**
* The label for child nodes (only for fields).
* E.g., "Models", "Compatible Parts"
*
* @return the child label
*/
String childLabel() default "";

/**
* Icon class for the node (optional).
* Uses Bootstrap Icons by default.
* E.g., "bi bi-car", "bi bi-gear"
*
* @return the icon class
*/
String icon() default "";

/**
* Order/priority for displaying this tree or child collection.
* Lower numbers appear first.
*
* @return the display order
*/
int order() default 0;
}
Loading