Skip to content

Commit

Permalink
Capability references like in the IDE
Browse files Browse the repository at this point in the history
  • Loading branch information
hpehl committed Oct 10, 2024
1 parent 24364cd commit 708d603
Show file tree
Hide file tree
Showing 18 changed files with 399 additions and 238 deletions.
14 changes: 14 additions & 0 deletions meta/src/main/java/org/jboss/hal/meta/AddressTemplate.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import java.util.List;
import java.util.function.Predicate;

import org.jboss.elemento.Id;
import org.jboss.hal.dmr.ModelNode;
import org.jboss.hal.dmr.ResourceAddress;
import org.jboss.hal.dmr.ValueEncoder;
Expand Down Expand Up @@ -276,6 +277,19 @@ public Iterator<Segment> iterator() {
return segments.iterator();
}

public String identifier() {
if (isEmpty()) {
return "root";
} else {
String safeTemplate = template
.replace("/", "-s-")
.replace("=", "-e-")
.replace(":", "-c-")
.replace("*", "-w-");
return Id.build(safeTemplate);
}
}

// ------------------------------------------------------ resolve

/** Resolve this template using the {@link NoopResolver} */
Expand Down
5 changes: 3 additions & 2 deletions meta/src/main/java/org/jboss/hal/meta/CapabilityRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ public Promise<List<String>> providerPoints(String capability) {
});
}

public Promise<List<AddressTemplate>> findReference(String capability, String value) {
public Promise<List<AddressTemplate>> findResources(String capability, String value) {
List<Task<FlowContext>> tasks = List.of(
context -> providerPoints(capability).then(pps -> context.resolve(PROVIDER_POINTS, pps)),
context -> {
Expand All @@ -90,7 +90,8 @@ public Promise<List<AddressTemplate>> findReference(String capability, String va
.failFast(false)
.then(context -> Promise.resolve(context.get(TEMPLATES, emptyList())))
.catch_(error -> {
logger.error("Unable to find capability %s for %s", capability, value);
logger.error("Unable to find resources for capability %s and value %s: %s", capability, value,
String.valueOf(error));
return Promise.resolve(emptyList());
});
}
Expand Down
38 changes: 38 additions & 0 deletions op/console/src/web/capability.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Copyright 2024 Red Hat
*
* Licensed 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
*
* https://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.
*/

.hal-c-capability-reference__menu {
background-color: var(--pf-v5-global--BackgroundColor--100);
box-shadow: var(--pf-v5-global--BoxShadow--lg);
padding: var(--pf-v5-global--spacer--sm);
max-width: 55ch;
}

.hal-c-capability-reference__menu-list {
max-height: 200px;
overflow-y: scroll;
}

.hal-c-capability-reference__provided-by {

.pf-v5-c-button.pf-m-link.pf-m-inline {
--pf-v5-c-button--m-link--Color: var(--pf-v5-global--Color--200);
}

.pf-v5-c-button.pf-m-link.pf-m-inline:hover {
--pf-v5-c-button--m-link--Color: var(--pf-v5-c-button--m-link--m-inline--hover--Color);
}
}
7 changes: 7 additions & 0 deletions op/console/src/web/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,16 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/

// External first
import "@patternfly/patternfly/patternfly.css";
import "@patternfly/patternfly/patternfly-addons.css";

// Variables second
import "./variables.css"

// Remaining third (a-z)
import "./capability.css"
import "./model-browser.css"
import "./resource-view.css"
import "./stability.css"
Expand Down
4 changes: 2 additions & 2 deletions op/console/src/web/model-browser.css
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@

.hal-c-model-browser__search-results {
--pf-v5-c-list--li--MarginTop: var(--pf-v5-global--spacer--xs);
max-height: 300px;
max-height: 280px;
overflow-y: scroll;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ public interface HalClasses {

// ------------------------------------------------------ constants (a-z)

String capabilityReference = "capability-reference";
String copy = "copy";
String deprecated = "deprecated";
String detail = "detail";
String content = "content";
String filtered = "filtered";
String goto_ = "goto";
String modelBrowser = "model-browser";
String providedBy = "provided-by";
String rbacHidden = "rbac-hidden";
String resourceView = "resource-view";
String results = "results";
Expand Down
16 changes: 14 additions & 2 deletions ui/src/main/java/org/jboss/hal/ui/modelbrowser/FindResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.util.Set;

import org.jboss.elemento.Id;
import org.jboss.elemento.Key;
import org.jboss.hal.meta.AddressTemplate;
import org.jboss.hal.meta.tree.TraverseContext;
import org.jboss.hal.meta.tree.TraverseContinuation;
Expand Down Expand Up @@ -52,6 +53,7 @@
import static org.jboss.elemento.Elements.setVisible;
import static org.jboss.elemento.Elements.span;
import static org.jboss.elemento.Elements.strong;
import static org.jboss.elemento.EventType.keydown;
import static org.jboss.hal.resources.HalClasses.halComponent;
import static org.jboss.hal.resources.HalClasses.modelBrowser;
import static org.jboss.hal.resources.HalClasses.results;
Expand Down Expand Up @@ -218,12 +220,22 @@ class FindResource {
FormGroup nameFormGroup = formGroup().fieldId(nameId).required()
.addLabel(formGroupLabel("Name"))
.addControl(nameControl = formGroupControl()
.addControl(nameInput = textInput(nameId)));
.addControl(nameInput = textInput(nameId)
.on(keydown, e -> {
if (Key.Enter.match(e)) {
search();
}
})));

FormGroup rootFormGroup = formGroup().fieldId(rootId)
.addLabel(formGroupLabel("Root"))
.addControl(formGroupControl()
.addControl(rootInput = textInput(rootId).value(modelBrowserTree.selectedAddress()))
.addControl(rootInput = textInput(rootId).value(modelBrowserTree.selectedAddress())
.on(keydown, e -> {
if (Key.Enter.match(e)) {
search();
}
}))
.addHelperText(helperText("Leave empty to search the whole model.")));

FormGroup excludeFormGroup = formGroup().fieldId(excludeId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@
import static org.jboss.hal.resources.HalClasses.halComponent;
import static org.jboss.hal.ui.StabilityLabel.stabilityLabel;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserNode.ROOT_ID;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserNode.uniqueId;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserNode.Type.FOLDER;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserNode.Type.RESOURCE;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserNode.Type.SINGLETON_RESOURCE;
Expand Down Expand Up @@ -140,7 +139,7 @@ private void fillBreadcrumb(ModelBrowserNode mbn) {
current = current.append(segment.key, segment.value);
final AddressTemplate finalTemplate = current;
boolean last = current.last().equals(mbn.template.last());
breadcrumb.addItem(breadcrumbItem(uniqueId(current), segment.key + "=" + segment.value)
breadcrumb.addItem(breadcrumbItem(current.identifier(), segment.key + "=" + segment.value)
.active(last)
.run(bci -> {
if (!last) {
Expand Down Expand Up @@ -189,7 +188,7 @@ private void clear() {
}

private HTMLElement copyToClipboard(AddressTemplate template) {
String copyToClipboardId = Id.build(uniqueId(template), "copy");
String copyToClipboardId = Id.unique("address", "copy");
String copyToClipboardText = "Copy address to clipboard";
Tooltip tooltip = tooltip(By.id(copyToClipboardId), copyToClipboardText)
.placement(auto)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ static List<ModelBrowserNode> parseChildren(ModelBrowserNode parent, ModelNode r
* Returns a function that turns a {@link ModelBrowserNode} into a {@link TreeViewItem}.
*/
static Function<ModelBrowserNode, TreeViewItem> mbn2tvi(Dispatcher dispatcher) {
return mbn -> treeViewItem(mbn.id)
return mbn -> treeViewItem(mbn.identifier)
.text(mbn.name)
.icon(mbn.type.icon.get())
.store(MODEL_BROWSER_NODE, mbn)
Expand All @@ -163,7 +163,7 @@ static Function<ModelBrowserNode, TreeViewItem> mbn2tvi(Dispatcher dispatcher) {
tvi.css(modifier(disabled));
// This popover is used for the initial load. It is removed together with the
// tree view item when the parent is collapsed.
tvi.add(popover(By.data(identifier, mbn.id))
tvi.add(popover(By.data(identifier, mbn.identifier))
.addHeader(mbn.name)
.addBody("Non-existing singleton resource"));
}
Expand All @@ -177,7 +177,7 @@ static Function<ModelBrowserNode, TreeViewItem> mbn2tvi(Dispatcher dispatcher) {
// This popover is used when the paren item is collapsed/expanded
// This is necessary because the initial popover has been removed
// on collapsed. It is removed automatically when the parent is collapsed.
item.add(popover(By.data(identifier, m.id))
item.add(popover(By.data(identifier, m.identifier))
.addHeader(m.name)
.addBody("Non-existing singleton resource"));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
import java.util.function.Supplier;

import org.gwtproject.safehtml.shared.SafeHtmlUtils;
import org.jboss.elemento.Id;
import org.jboss.hal.meta.AddressTemplate;
import org.patternfly.icon.IconSets;
import org.patternfly.icon.PredefinedIcon;
Expand All @@ -34,19 +33,6 @@ class ModelBrowserNode {

static final String ROOT_ID = "root";

static String uniqueId(AddressTemplate template) {
if (template.isEmpty()) {
return ROOT_ID;
} else {
String safeTemplate = template.template
.replace("/", "-s-")
.replace("=", "-e-")
.replace(":", "-c-")
.replace("*", "-w-");
return Id.build(safeTemplate);
}
}

enum Type {
SINGLETON_FOLDER(IconSets.fas::listUl, null),

Expand All @@ -65,15 +51,15 @@ enum Type {
}
}

final String id;
final String identifier;
final AddressTemplate template;
final String name;
final Type type;
final List<ModelBrowserNode> children;
boolean exists;

ModelBrowserNode(AddressTemplate template, String name, Type type) {
this.id = uniqueId(template);
this.identifier = template.identifier();
this.template = template;
this.name = name != null ? SafeHtmlUtils.htmlEscape(name) : null;
this.type = type;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@ public interface ModelBrowserSelectEvent extends UIEvent {
* @param source the source element used to dispatch the event.
* @param address the address used to create the event's detail.
*/
static void dispatch(HTMLElement source, String address) {
static void dispatch(HTMLElement source, AddressTemplate template) {
//noinspection unchecked
CustomEventInit<String> init = CustomEventInit.create();
init.setBubbles(true);
init.setCancelable(true);
init.setDetail(address);
init.setDetail(template.template);
CustomEvent<String> event = new CustomEvent<>(TYPE, init);
source.dispatchEvent(event);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,13 +40,10 @@
import static org.jboss.hal.resources.HalClasses.halComponent;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserEngine.MODEL_BROWSER_NODE;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserEngine.mbn2tvi;
import static org.jboss.hal.ui.modelbrowser.ModelBrowserNode.uniqueId;
import static org.patternfly.component.button.Button.button;
import static org.patternfly.component.page.PageMainSection.pageMainSection;
import static org.patternfly.component.toolbar.Toolbar.toolbar;
import static org.patternfly.component.toolbar.ToolbarContent.toolbarContent;
import static org.patternfly.component.toolbar.ToolbarGroup.toolbarGroup;
import static org.patternfly.component.toolbar.ToolbarGroupType.iconButtonGroup;
import static org.patternfly.component.toolbar.ToolbarItem.toolbarItem;
import static org.patternfly.component.tooltip.Tooltip.tooltip;
import static org.patternfly.component.tree.TreeView.treeView;
Expand Down Expand Up @@ -105,14 +102,13 @@ class ModelBrowserTree implements IsElement<HTMLElement> {
.add(pageMainSection().sticky(Sticky.top).padding(noPadding)
.add(toolbar().css(modifier(insetNone))
.addContent(toolbarContent()
.addGroup(toolbarGroup(iconButtonGroup)
.addItem(toolbarItem().add(backButton))
.addItem(toolbarItem().add(forwardButton))
.addItem(toolbarItem().add(reloadButton))
.addItem(toolbarItem().add(homeButton))
.addItem(toolbarItem().add(findResource))
.addItem(toolbarItem().add(gotoResource))
.addItem(toolbarItem().add(collapseButton))))))
.addItem(toolbarItem().css(modifier("spacer-none")).add(backButton))
.addItem(toolbarItem().css(modifier("spacer-none")).add(forwardButton))
.addItem(toolbarItem().css(modifier("spacer-none")).add(reloadButton))
.addItem(toolbarItem().css(modifier("spacer-none")).add(homeButton))
.addItem(toolbarItem().css(modifier("spacer-none")).add(findResource))
.addItem(toolbarItem().css(modifier("spacer-none")).add(gotoResource))
.addItem(toolbarItem().css(modifier("spacer-none")).add(collapseButton)))))
.add(pageMainSection().padding(noPadding).add(treeView))
.element();
}
Expand Down Expand Up @@ -145,30 +141,30 @@ void select(String identifier) {
}

void select(ModelBrowserNode parent, ModelBrowserNode child) {
TreeViewItem parentItem = treeView.findItem(parent.id);
TreeViewItem parentItem = treeView.findItem(parent.identifier);
if (parentItem != null) {
if (!parentItem.expanded() && parentItem.status() == pending) {
parentItem.load().then(__ -> {
treeView.select(child.id);
treeView.select(child.identifier);
return null;
});
} else if (!parentItem.contains(child.id)) {
} else if (!parentItem.contains(child.identifier)) {
// child might have been added externally in CLI or other management tools
parentItem.reload().then(__ -> {
treeView.select(child.id);
treeView.select(child.identifier);
return null;
});
} else {
treeView.select(child.id);
treeView.select(child.identifier);
}
} else {
treeView.select(child.id);
treeView.select(child.identifier);
}
}

void select(AddressTemplate template) {
if (!template.isEmpty() && template.fullyQualified()) {
TreeViewItem item = treeView.findItem(uniqueId(template));
TreeViewItem item = treeView.findItem(template.identifier());
if (item != null) {
treeView.select(item);
} else {
Expand All @@ -178,12 +174,12 @@ void select(AddressTemplate template) {
// Build a template up to the last valid segment.
AddressTemplate current = AddressTemplate.root();
for (Segment segment : template) {
if (treeView.findItem(uniqueId(current.append(segment.key, segment.value))) == null) {
if (treeView.findItem(current.append(segment.key, segment.value).identifier()) == null) {
break;
}
current = current.append(segment.key, segment.value);
}
treeView.select(uniqueId(current));
treeView.select(current.identifier());
} else {
logger.error("Unable to select template %s: %s", template, context.failure());
}
Expand Down Expand Up @@ -238,8 +234,8 @@ private List<Task<FlowContext>> selectTasks(AddressTemplate template) {
List<Task<FlowContext>> tasks = new ArrayList<>();
AddressTemplate current = AddressTemplate.root();
for (Segment segment : template) {
String wildcardItemId = uniqueId(current.append(segment.key, "*"));
String valueItemId = uniqueId(current.append(segment.key, segment.value));
String wildcardItemId = current.append(segment.key, "*").identifier();
String valueItemId = current.append(segment.key, segment.value).identifier();
tasks.add(context -> treeView.load(wildcardItemId).then(items -> context.resolve()));
tasks.add(context -> treeView.load(valueItemId).then(items -> context.resolve()));
current = current.append(segment.key, segment.value);
Expand Down
Loading

0 comments on commit 708d603

Please sign in to comment.