This is an automated email from the ASF dual-hosted git repository.

jamesbognar pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/juneau.git

commit 99fc927e9bfb28cc11d777657be453dcccd9a190
Author: James Bognar <[email protected]>
AuthorDate: Thu Aug 20 11:35:18 2026 -0400

    TODO-445a: Add juneau-rest-server-widgets module with ActionBar, ActionRef, 
and SafeAction
    
    Extract a reusable widget toolkit so views can compose row-detail action 
bars without inlining markup.
---
 juneau-bom/pom.xml                                 |   1 +
 juneau-rest/juneau-rest-server-widgets/pom.xml     | 122 +++++++++++++++++++++
 .../juneau/rest/server/widgets/ActionBar.java      |  74 +++++++++++++
 .../juneau/rest/server/widgets/ActionBarItem.java  |  26 +++++
 .../juneau/rest/server/widgets/ActionRef.java      |  49 +++++++++
 .../juneau/rest/server/widgets/SafeAction.java     |  59 ++++++++++
 .../apache/juneau/rest/server/widgets/Widget.java  |  37 +++++++
 .../juneau/rest/server/widgets/package-info.java   |  35 ++++++
 .../juneau/rest/server/widgets/ActionBar_Test.java |  78 +++++++++++++
 juneau-rest/pom.xml                                |   1 +
 10 files changed, 482 insertions(+)

diff --git a/juneau-bom/pom.xml b/juneau-bom/pom.xml
index 4c0468308c..8530277776 100644
--- a/juneau-bom/pom.xml
+++ b/juneau-bom/pom.xml
@@ -62,6 +62,7 @@
                        
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-tracing-otel</artifactId><version>${project.version}</version></dependency>
                        
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-management-logging</artifactId><version>${project.version}</version></dependency>
                        
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-datatables</artifactId><version>${project.version}</version></dependency>
+                       
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-widgets</artifactId><version>${project.version}</version></dependency>
                        
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-views</artifactId><version>${project.version}</version></dependency>
                        
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-console-ui</artifactId><version>${project.version}</version></dependency>
                        
<dependency><groupId>org.apache.juneau</groupId><artifactId>juneau-rest-server-console-ui-freemarker</artifactId><version>${project.version}</version></dependency>
diff --git a/juneau-rest/juneau-rest-server-widgets/pom.xml 
b/juneau-rest/juneau-rest-server-widgets/pom.xml
new file mode 100644
index 0000000000..650890f2ab
--- /dev/null
+++ b/juneau-rest/juneau-rest-server-widgets/pom.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  Licensed to the Apache Software Foundation (ASF) under one or more
+  contributor license agreements.  See the NOTICE file distributed with
+  this work for additional information regarding copyright ownership.
+  The ASF licenses this file to You under the Apache License, Version 2.0
+  (the "License"); you may not use this file except in compliance with
+  the License.  You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
https://maven.apache.org/xsd/maven-4.0.0.xsd";>
+
+       <modelVersion>4.0.0</modelVersion>
+
+       <parent>
+               <groupId>org.apache.juneau</groupId>
+               <artifactId>juneau-rest</artifactId>
+               <version>10.0.0-SNAPSHOT</version>
+       </parent>
+
+       <artifactId>juneau-rest-server-widgets</artifactId>
+       <name>Apache Juneau REST Server Widgets</name>
+       <description>Apache Juneau REST Server - reusable widget primitives 
(ActionBar and shared Widget contract). Table-specific types stay in 
juneau-rest-server-views; this module never depends on views.</description>
+       <packaging>bundle</packaging>
+
+       <properties>
+               
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+       </properties>
+
+       <dependencies>
+               <dependency>
+                       <groupId>org.apache.juneau</groupId>
+                       <artifactId>juneau-commons</artifactId>
+                       <version>${project.version}</version>
+               </dependency>
+
+               <!-- Test scope -->
+               <dependency>
+                       <groupId>org.junit.jupiter</groupId>
+                       <artifactId>junit-jupiter</artifactId>
+                       <version>${junit.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.juneau</groupId>
+                       <artifactId>juneau-test-utils</artifactId>
+                       <version>${project.version}</version>
+                       <scope>test</scope>
+               </dependency>
+               <dependency>
+                       <groupId>org.apache.juneau</groupId>
+                       <artifactId>juneau-test</artifactId>
+                       <version>${project.version}</version>
+                       <scope>test</scope>
+               </dependency>
+       </dependencies>
+
+       <build>
+               <plugins>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-source-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <id>attach-sources</id>
+                                               <phase>verify</phase>
+                                               <goals>
+                                                       <goal>jar-no-fork</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.felix</groupId>
+                               <artifactId>maven-bundle-plugin</artifactId>
+                               <extensions>true</extensions>
+                               <configuration>
+                                       
<supportIncrementalBuild>true</supportIncrementalBuild>
+                               </configuration>
+                               <executions>
+                                       <execution>
+                                               <id>bundle-manifest</id>
+                                               <phase>process-classes</phase>
+                                               <goals>
+                                                       <goal>manifest</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.apache.maven.plugins</groupId>
+                               <artifactId>maven-jar-plugin</artifactId>
+                       </plugin>
+                       <plugin>
+                               <groupId>org.jacoco</groupId>
+                               <artifactId>jacoco-maven-plugin</artifactId>
+                               <executions>
+                                       <execution>
+                                               <id>default-prepare-agent</id>
+                                               <goals>
+                                                       
<goal>prepare-agent</goal>
+                                               </goals>
+                                       </execution>
+                                       <execution>
+                                               <id>default-report</id>
+                                               <phase>prepare-package</phase>
+                                               <goals>
+                                                       <goal>report</goal>
+                                               </goals>
+                                       </execution>
+                               </executions>
+                       </plugin>
+               </plugins>
+       </build>
+</project>
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionBar.java
 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionBar.java
new file mode 100644
index 0000000000..4f9f422b3f
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionBar.java
@@ -0,0 +1,74 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.widgets;
+
+import static org.apache.juneau.commons.utils.Shorts.*;
+
+import java.util.*;
+
+/**
+ * An ordered bar of {@link ActionRef} ids and {@link SafeAction}s.
+ *
+ * <p>
+ * Holds ids only &mdash; it does <b>not</b> import any views-module 
write-action type.  CSRF, confirm, and
+ * write-result handling stay on the enclosing view's action catalog.
+ *
+ * @since 10.0.0
+ */
+public class ActionBar implements Widget {
+
+       /** The frozen contract version for this widget. */
+       public static final String CONTRACT_VERSION = "1";
+
+       /** The ordered items; omitted / empty means no bar. */
+       public List<ActionBarItem> items;
+
+       /**
+        * Creates an empty action bar.
+        *
+        * @return A new {@link ActionBar}.
+        */
+       public static ActionBar create() {
+               return new ActionBar();
+       }
+
+       /**
+        * Sets the ordered items.
+        *
+        * @param value The items, in display order.  Must not be <jk>null</jk>.
+        * @return This object.
+        */
+       public ActionBar items(ActionBarItem...value) {
+               items = l(value);
+               return this;
+       }
+
+       @Override /* Widget */
+       public void validate() {
+               if (items == null)
+                       return;
+               for (var item : items) {
+                       if (item == null)
+                               throw iaex("ActionBar item must not be null.");
+                       if (item instanceof ActionRef ar) {
+                               if (ar.id == null || ar.id.isBlank())
+                                       throw iaex("ActionRef id must not be 
null or blank.");
+                       } else if (!(item instanceof SafeAction))
+                               throw iaex("ActionBar item must be ActionRef or 
SafeAction.");
+               }
+       }
+}
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionBarItem.java
 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionBarItem.java
new file mode 100644
index 0000000000..d2cf7c3555
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionBarItem.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.widgets;
+
+/**
+ * One item in an {@link ActionBar}: either an {@link ActionRef} (opaque id 
naming a write action on the
+ * enclosing view) or a {@link SafeAction} (client-only, no endpoint).
+ *
+ * @since 10.0.0
+ */
+public interface ActionBarItem {
+}
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionRef.java
 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionRef.java
new file mode 100644
index 0000000000..b0755c6225
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/ActionRef.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.widgets;
+
+import static org.apache.juneau.commons.utils.Shorts.*;
+
+/**
+ * An opaque id naming a write action on the enclosing view.
+ *
+ * <p>
+ * This type deliberately does <b>not</b> import any views-module type.  
Existence of the named action on the
+ * enclosing view's action catalog is checked in views ({@code 
RowDetailDef}/{@code ViewDef.validate()}), never
+ * here.  The bar does not grow its own write protocol (no endpoint / method / 
csrf fields).
+ *
+ * @since 10.0.0
+ */
+public class ActionRef implements ActionBarItem {
+
+       /** The opaque action id.  Must not be blank. */
+       public String id;
+
+       /**
+        * Creates an action reference with the specified id.
+        *
+        * @param id The action id.  Must not be <jk>null</jk> or blank.
+        * @return A new {@link ActionRef}.
+        */
+       public static ActionRef of(String id) {
+               if (id == null || id.isBlank())
+                       throw iaex("ActionRef id must not be null or blank.");
+               var a = new ActionRef();
+               a.id = id;
+               return a;
+       }
+}
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/SafeAction.java
 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/SafeAction.java
new file mode 100644
index 0000000000..aa17e10c06
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/SafeAction.java
@@ -0,0 +1,59 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.widgets;
+
+/**
+ * A client-only {@link ActionBar} item with no endpoint.
+ *
+ * <p>
+ * This slice ships {@link #COLLAPSE} (collapse the child row).  Unlike an 
{@link ActionRef}, a safe action is
+ * enabled immediately &mdash; including during an in-flight expand GET and 
after a failed GET &mdash; so the
+ * user can dismiss a loading or error panel.
+ *
+ * @since 10.0.0
+ */
+public enum SafeAction implements ActionBarItem {
+
+       /** Collapse the expanded child row. */
+       COLLAPSE("collapse", "Collapse");
+
+       private final String wire;
+       private final String label;
+
+       SafeAction(String wire, String label) {
+               this.wire = wire;
+               this.label = label;
+       }
+
+       /**
+        * Returns the wire token stamped onto {@code data-juneau-safe}.
+        *
+        * @return The wire token (e.g. {@code "collapse"}).
+        */
+       public String wire() {
+               return wire;
+       }
+
+       /**
+        * Returns the built-in button label, painted with {@code textContent}.
+        *
+        * @return The label.
+        */
+       public String label() {
+               return label;
+       }
+}
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/Widget.java
 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/Widget.java
new file mode 100644
index 0000000000..e4f5c18736
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/Widget.java
@@ -0,0 +1,37 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.widgets;
+
+/**
+ * Marker for a reusable widget primitive.
+ *
+ * <p>
+ * Each concrete type owns a {@code public static final String 
CONTRACT_VERSION} (starting at {@code "1"}) and
+ * implements {@link #validate()} as a fail-closed bean-level check.  
Serving-path call sites (for example a
+ * table emitter) must invoke {@code validate()} rather than treating it as 
documentation-only.
+ *
+ * @since 10.0.0
+ */
+public interface Widget {
+
+       /**
+        * Fail-closed bean validation.
+        *
+        * @throws IllegalArgumentException If this widget is not well-formed.
+        */
+       void validate();
+}
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/package-info.java
 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/package-info.java
new file mode 100644
index 0000000000..e84bd72f99
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/main/java/org/apache/juneau/rest/server/widgets/package-info.java
@@ -0,0 +1,35 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * Reusable widget primitives for the Juneau REST server toolkit.
+ *
+ * <p>
+ * This optional module holds the shared {@link 
org.apache.juneau.rest.server.widgets.Widget} marker and the first
+ * concrete primitive, {@link 
org.apache.juneau.rest.server.widgets.ActionBar}.  Table-specific types
+ * (row-detail defs, row actions) stay in {@code juneau-rest-server-views}; 
this module has <b>no</b> dependency
+ * on views, so an {@link org.apache.juneau.rest.server.widgets.ActionBar} can 
never import a row-action type.
+ *
+ * <h5 class='section'>See Also:</h5>
+ * <ul>
+ *     <li class='jc'>{@link org.apache.juneau.rest.server.widgets.Widget}
+ *     <li class='jc'>{@link org.apache.juneau.rest.server.widgets.ActionBar}
+ * </ul>
+ *
+ * @since 10.0.0
+ */
+package org.apache.juneau.rest.server.widgets;
diff --git 
a/juneau-rest/juneau-rest-server-widgets/src/test/java/org/apache/juneau/rest/server/widgets/ActionBar_Test.java
 
b/juneau-rest/juneau-rest-server-widgets/src/test/java/org/apache/juneau/rest/server/widgets/ActionBar_Test.java
new file mode 100644
index 0000000000..8ad06c95cf
--- /dev/null
+++ 
b/juneau-rest/juneau-rest-server-widgets/src/test/java/org/apache/juneau/rest/server/widgets/ActionBar_Test.java
@@ -0,0 +1,78 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.juneau.rest.server.widgets;
+
+import static org.apache.juneau.test.bct.BctAssertions.*;
+import static org.junit.jupiter.api.Assertions.*;
+
+import java.nio.file.*;
+
+import org.apache.juneau.*;
+import org.junit.jupiter.api.*;
+
+/**
+ * {@link ActionBar} / {@link ActionRef} / {@link SafeAction} bean contract, 
including the views-module isolation
+ * rule (this module must never import {@code RowAction}).
+ */
+class ActionBar_Test extends TestBase {
+
+       @Test void a01_contractVersion_isOne() {
+               assertEquals("1", ActionBar.CONTRACT_VERSION);
+       }
+
+       @Test void a02_items_roundTrip() {
+               var bar = ActionBar.create().items(ActionRef.of("ack"), 
SafeAction.COLLAPSE);
+               assertSize(2, bar.items);
+               assertEquals("ack", ((ActionRef) bar.items.get(0)).id);
+               assertEquals(SafeAction.COLLAPSE, bar.items.get(1));
+               bar.validate();
+       }
+
+       @Test void a03_blankActionRef_rejectedAtFactory() {
+               assertThrows(IllegalArgumentException.class, () -> 
ActionRef.of(null));
+               assertThrows(IllegalArgumentException.class, () -> 
ActionRef.of("  "));
+       }
+
+       @Test void a04_validate_rejectsBlankActionRefId() {
+               var bar = ActionBar.create();
+               var blank = new ActionRef();
+               blank.id = "  ";
+               bar.items = java.util.List.of(blank);
+               var e = assertThrows(IllegalArgumentException.class, 
bar::validate);
+               assertTrue(e.getMessage().contains("ActionRef"), e::getMessage);
+       }
+
+       @Test void a05_safeAction_collapseWireAndLabel() {
+               assertEquals("collapse", SafeAction.COLLAPSE.wire());
+               assertEquals("Collapse", SafeAction.COLLAPSE.label());
+       }
+
+       @Test void a06_sources_doNotImportRowAction() throws Exception {
+               var root = Path.of("").toAbsolutePath();
+               var src = root;
+               if (!Files.isDirectory(src.resolve("src/main/java")))
+                       src = 
root.resolve("juneau-rest/juneau-rest-server-widgets");
+               assertTrue(Files.isDirectory(src.resolve("src/main/java")), 
src::toString);
+               try (var walk = Files.walk(src.resolve("src/main/java"))) {
+                       for (var f : walk.filter(p -> 
p.toString().endsWith(".java")).toList()) {
+                               var text = Files.readString(f);
+                               assertFalse(text.contains("import 
org.apache.juneau.rest.server.views.RowAction"),
+                                       () -> "widgets module must not import 
RowAction: " + f);
+                       }
+               }
+       }
+}
diff --git a/juneau-rest/pom.xml b/juneau-rest/pom.xml
index 47781c6716..0d8a964dc3 100644
--- a/juneau-rest/pom.xml
+++ b/juneau-rest/pom.xml
@@ -47,6 +47,7 @@
                <module>juneau-rest-server-tracing-otel</module>
                <module>juneau-rest-server-management-logging</module>
                <module>juneau-rest-server-datatables</module>
+               <module>juneau-rest-server-widgets</module>
                <module>juneau-rest-server-views</module>
                <module>juneau-rest-server-views-markdown</module>
                <module>juneau-rest-server-console-ui</module>

Reply via email to