Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add icons to Command Palette #10049

Open
wants to merge 20 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
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
5 changes: 5 additions & 0 deletions core/src/main/java/hudson/model/Computer.java
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,11 @@ public String getSearchUrl() {
return getUrl();
}

@Override
public String getSearchIcon() {
return this.getIconClassName();
}
janfaracik marked this conversation as resolved.
Show resolved Hide resolved

/**
* {@link RetentionStrategy} associated with this computer.
*
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/hudson/model/Job.java
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,11 @@ public boolean supportsLogRotator() {
return true;
}

@Override
public String getSearchIcon() {
return "symbol-status-" + this.getIconColor().getIconName();
}

@Override
protected SearchIndexBuilder makeSearchIndex() {
return super.makeSearchIndex().add(new SearchIndex() {
Expand Down
6 changes: 6 additions & 0 deletions core/src/main/java/hudson/model/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
import hudson.security.AccessControlled;
import hudson.security.SecurityRealm;
import hudson.security.UserMayOrMayNotExistException2;
import hudson.tasks.UserAvatarResolver;
import hudson.util.FormValidation;
import hudson.util.RunList;
import hudson.util.XStream2;
Expand Down Expand Up @@ -277,6 +278,11 @@ public String getId() {
return "/user/" + Util.rawEncode(idStrategy().keyFor(id));
}

@Override
public String getSearchIcon() {
return UserAvatarResolver.resolve(this, "48x48");
}

/**
* The URL of the user page.
*/
Expand Down
5 changes: 5 additions & 0 deletions core/src/main/java/hudson/model/View.java
Original file line number Diff line number Diff line change
Expand Up @@ -560,6 +560,11 @@ public String getSearchUrl() {
return getUrl();
}

@Override
public String getSearchIcon() {
return "symbol-jobs";
}

/**
* Returns the transient {@link Action}s associated with the top page.
*
Expand Down
49 changes: 44 additions & 5 deletions core/src/main/java/hudson/search/Search.java
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@
import jenkins.security.stapler.StaplerNotDispatchable;
import jenkins.util.MemoryReductionUtil;
import jenkins.util.SystemProperties;
import org.jenkins.ui.symbol.Symbol;
import org.jenkins.ui.symbol.SymbolRequest;
import org.kohsuke.accmod.Restricted;
import org.kohsuke.accmod.restrictions.NoExternalUse;
import org.kohsuke.stapler.Ancestor;
Expand All @@ -56,6 +58,7 @@
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.StaplerResponse2;
import org.kohsuke.stapler.export.DataWriter;
import org.kohsuke.stapler.export.ExportConfig;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;
import org.kohsuke.stapler.export.Flavor;
Expand Down Expand Up @@ -157,10 +160,23 @@ public void doSuggestOpenSearch(StaplerRequest2 req, StaplerResponse2 rsp, @Quer
*/
public void doSuggest(StaplerRequest2 req, StaplerResponse2 rsp, @QueryParameter String query) throws IOException, ServletException {
Result r = new Result();
for (SuggestedItem item : getSuggestions(req, query))
r.suggestions.add(new Item(item.getPath(), item.getUrl()));
for (SuggestedItem curItem : getSuggestions(req, query)) {
String iconName = curItem.item.getSearchIcon();

rsp.serveExposedBean(req, r, Flavor.JSON);
if (iconName == null ||
(!iconName.startsWith("symbol-") && !iconName.startsWith("http"))
) {
iconName = "symbol-search";
}

if (iconName.startsWith("symbol")) {
r.suggestions.add(new Item(curItem.getPath(), curItem.getUrl(),
Symbol.get(new SymbolRequest.Builder().withRaw(iconName).build())));
} else {
r.suggestions.add(new Item(curItem.getPath(), curItem.getUrl(), iconName, "image"));
}
}
rsp.serveExposedBean(req, r, new ExportConfig());
}

/**
Expand Down Expand Up @@ -259,19 +275,42 @@ public static class Item {

private final String url;

private final String type;

public final String iconXml;

public Item(String name) {
this(name, null);
this(name, null, null);
}

public Item(String name, String url, String iconXml) {
this.name = name;
this.url = url;
this.iconXml = iconXml;
this.type = "symbol";
}

public Item(String name, String url) {
public Item(String name, String url, String iconXml, String type) {
this.name = name;
this.url = url;
this.iconXml = iconXml;
this.type = type;
}

@Exported
public String getUrl() {
return url;
}

@Exported
public String getIconXml() {
return iconXml;
}

@Exported
public String getType() {
return type;
}
}

private enum Mode {
Expand Down
9 changes: 9 additions & 0 deletions core/src/main/java/hudson/search/SearchItem.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
package hudson.search;

import hudson.model.Build;
import org.jenkins.ui.icon.IconSpec;

/**
* Represents an item reachable from {@link SearchIndex}.
Expand Down Expand Up @@ -54,6 +55,14 @@ public interface SearchItem {

String getSearchUrl();

default String getSearchIcon() {
if (this instanceof IconSpec) {
return ((IconSpec) this).getIconClassName();
}

return "symbol-search";
}

/**
* Returns the {@link SearchIndex} to further search sub items inside this item.
*
Expand Down
27 changes: 24 additions & 3 deletions core/src/main/java/jenkins/model/Jenkins.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@
import hudson.scm.RepositoryBrowser;
import hudson.scm.SCM;
import hudson.search.CollectionSearchIndex;
import hudson.search.SearchIndex;
import hudson.search.SearchIndexBuilder;
import hudson.search.SearchItem;
import hudson.security.ACL;
Expand Down Expand Up @@ -2345,9 +2346,29 @@ public String getSearchUrl() {
@Override
public SearchIndexBuilder makeSearchIndex() {
SearchIndexBuilder builder = super.makeSearchIndex();
if (hasPermission(ADMINISTER)) {
builder.add("manage", Messages.ManageJenkinsAction_DisplayName());
}

this.actions.stream().filter(e -> e.getIconFileName() != null).forEach(action -> builder.add(new SearchItem() {
@Override
public String getSearchName() {
return action.getDisplayName();
}

@Override
public String getSearchUrl() {
return action.getUrlName();
}

@Override
public String getSearchIcon() {
return action.getIconFileName();
}

@Override
public SearchIndex getSearchIndex() {
return SearchIndex.EMPTY;
}
}));

builder.add(new CollectionSearchIndex<TopLevelItem>() {
@Override
protected SearchItem get(String key) { return getItemByFullName(key, TopLevelItem.class); }
Expand Down
4 changes: 2 additions & 2 deletions src/main/js/components/command-palette/datasources.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import { LinkResult } from "./models";
import Search from "@/api/search";
import * as Symbols from "./symbols";

export const JenkinsSearchSource = {
execute(query) {
Expand All @@ -18,7 +17,8 @@ export const JenkinsSearchSource = {
rsp.json().then((data) => {
return data["suggestions"].slice().map((e) =>
LinkResult({
icon: Symbols.SEARCH,
icon: e.iconXml,
type: e.type,
label: e.name,
url: correctAddress(e.url),
}),
Expand Down
19 changes: 17 additions & 2 deletions src/main/js/components/command-palette/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ function init() {
results = Promise.all([
LinkResult({
icon: Symbols.HELP,
type: "symbol",
label: i18n.dataset.getHelp,
url: headerCommandPaletteButton.dataset.searchHelpUrl,
isExternal: true,
Expand Down Expand Up @@ -94,18 +95,23 @@ function init() {
}

searchResultsContainer.style.height = searchResults.offsetHeight + "px";
debouncedSpinner.cancel();
commandPaletteSearchBarContainer.classList.remove(
"jenkins-search--loading",
);
});
}

const debouncedSpinner = debounce(() => {
commandPaletteSearchBarContainer.classList.add("jenkins-search--loading");
}, 150);

const debouncedLoad = debounce(() => {
renderResults();
}, 150);

commandPaletteInput.addEventListener("input", () => {
commandPaletteSearchBarContainer.classList.add("jenkins-search--loading");
debouncedSpinner();
debouncedLoad();
});

Expand All @@ -119,7 +125,16 @@ function init() {
}

function hideCommandPalette() {
commandPalette.close();
commandPalette.setAttribute("closing", "");

commandPalette.addEventListener(
"animationend",
() => {
commandPalette.removeAttribute("closing");
commandPalette.close();
},
{ once: true },
);
}

function itemMouseEnter(item) {
Expand Down
6 changes: 3 additions & 3 deletions src/main/js/components/command-palette/models.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { xmlEscape } from "@/util/security";
* @param {Object} params
* @param {string} params.icon
* @param {string} params.label
* @param {string} params.type
* @param {string} params.url
* @param {boolean | undefined} params.isExternal
*/
Expand All @@ -16,9 +17,8 @@ export function LinkResult(params) {
return `<a class="jenkins-command-palette__results__item" href="${xmlEscape(
params.url,
)}">
<div class="jenkins-command-palette__results__item__icon">${
params.icon
}</div>
${params.type === "image" ? `<img alt="${xmlEscape(params.label)}" class="jenkins-command-palette__results__item__icon" src="${params.icon}" />` : ""}
${params.type !== "image" ? `<div class="jenkins-command-palette__results__item__icon">${params.icon}</div>` : ""}
${xmlEscape(params.label)}
${params.isExternal ? Symbols.EXTERNAL_LINK : ""}
</a>`;
Expand Down
1 change: 0 additions & 1 deletion src/main/js/components/command-palette/symbols.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading