Skip to content

Commit

Permalink
Refactor with ES6 classes
Browse files Browse the repository at this point in the history
  • Loading branch information
janfaracik committed May 24, 2022
1 parent 4cb4af6 commit 684997d
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
</div>

<div class="login page-header__hyperlinks">
<button id="button-spotlight" tooltip="${%Search}" data-keyboard-shortcut="CMD+K">
<button id="button-open-command-palette" tooltip="${%Search}" data-keyboard-shortcut="CMD+K">
<l:icon src="symbol-search" />
</button>

Expand Down
14 changes: 7 additions & 7 deletions core/src/main/resources/lib/layout/search.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,26 @@ THE SOFTWARE.
The command center overlay for Jenkins
</s:documentation>

<div id="command-center-i18n" class="i18n"
<div id="command-palette-i18n" class="i18n"
data-no-results-for="${%No results for}"
data-help="${%Help}"
data-get-help="${%Get help using Jenkins search}"
/>

<dialog id="command-center" class="jenkins-command-center__wrapper">
<div class="jenkins-command-center">
<div class="jenkins-command-center__search">
<dialog id="command-palette" class="jenkins-command-palette__wrapper">
<div class="jenkins-command-palette">
<div class="jenkins-command-palette__search">
<div class="icon">
<l:icon src="symbol-search" />
</div>
<input id="command-bar" placeholder="${%Search}" type="search" autocomplete="off" autocorrect="off"
autocapitalize="off" spellcheck="false" />
<div class="keyboard-shortcuts" id="command-center-keyboard-shortcut">
<div class="keyboard-shortcuts" id="command-palette-keyboard-shortcut">

</div>
</div>
<div id="search-results-container" class="jenkins-command-center__results-container">
<div id="search-results" class="jenkins-command-center__results" />
<div id="search-results-container" class="jenkins-command-palette__results-container">
<div id="search-results" class="jenkins-command-palette__results" />
</div>
</div>
</dialog>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
import "regenerator-runtime/runtime"
import Search from "./api/search";
import "regenerator-runtime/runtime";
import CommandPaletteService from "./services";
import {LinkResult} from "@/components/command-palette/models";
import * as Symbols from "./symbols";

window.addEventListener('load', () => {
const i18n = document.getElementById("command-center-i18n")
const headerCommandPaletteButton = document.getElementById("button-spotlight")
const commandPalette = document.getElementById("command-center")
const i18n = document.getElementById("command-palette-i18n")
const headerCommandPaletteButton = document.getElementById("button-open-command-palette");
const commandPalette = document.getElementById("command-palette")
const commandPaletteInput = document.getElementById("command-bar")
const commandPaletteLoadingSymbol = commandPalette.querySelector(".jenkins-command-center__search .icon")
const commandPaletteLoadingSymbol = commandPalette.querySelector(".jenkins-command-palette__search .icon")
const searchResults = document.getElementById("search-results")
const searchResultsContainer = document.getElementById("search-results-container")

const hoverClass = "jenkins-command-center__results__item--hover";
const hoverClass = "jenkins-command-palette__results__item--hover";

// Events
headerCommandPaletteButton.addEventListener("click", function () {
Expand All @@ -31,46 +33,39 @@ window.addEventListener('load', () => {

commandPaletteInput.addEventListener("input", async (e) => {
commandPaletteLoadingSymbol.classList.add("icon--loading")
let results
const query = e.target.value;
let results;

if (e.target.value.length === 0) {
if (query.length === 0) {
results = {
[i18n.dataset.help]: [
{
icon: {
svg: "<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\"><path d=\"M256 80a176 176 0 10176 176A176 176 0 00256 80z\" fill=\"none\" stroke=\"currentColor\" stroke-miterlimit=\"10\" stroke-width=\"32\"/><path d=\"M200 202.29s.84-17.5 19.57-32.57C230.68 160.77 244 158.18 256 158c10.93-.14 20.69 1.67 26.53 4.45 10 4.76 29.47 16.38 29.47 41.09 0 26-17 37.81-36.37 50.8S251 281.43 251 296\" fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-miterlimit=\"10\" stroke-width=\"28\"/><circle cx=\"250\" cy=\"348\" r=\"20\" fill=\"currentColor\"/></svg>"
},
name: i18n.dataset.getHelp,
url: document.getElementById("page-header").dataset.searchHelpUrl.escapeHTML()
}
new LinkResult(
{svg: Symbols.HELP},
i18n.dataset.getHelp,
undefined,
undefined,
document.getElementById("page-header").dataset.searchHelpUrl.escapeHTML(),
true
)
]
}
} else {
const response = await Search.search(e.target.value);
const result = await response.json();

// Group the results
results = groupByKey(result["suggestions"], "category")
results = await CommandPaletteService.getResults(query);
}

// Clear current search results
searchResults.innerHTML = ""

if (e.target.value.length === 0 || Object.keys(results).length > 0) {
if (query.length === 0 || Object.keys(results).length > 0) {
for (const [category, items] of Object.entries(results)) {
const heading = document.createElement("p")
heading.className = "jenkins-command-center__results__heading"
heading.className = "jenkins-command-palette__results__heading"
heading.innerText = category
searchResults.append(heading)

items.forEach(function (obj) {
let link = document.createElement("DIV")
link.innerHTML = `<a class="jenkins-command-center__results__item" href="${obj.url}">
<div class="jenkins-command-center__results__item__icon">${obj.icon ? `${obj.icon.svg ? obj.icon.svg : `<img src="${obj.icon.url}" alt="" />`}` : ``}</div>
${obj.name}
${obj.description ? `<span class="jenkins-command-center__results__item__description">${obj.description}</span>` : ``}
<svg class="jenkins-command-center__results__item__chevron" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48" d="M184 112l144 144-144 144"/></svg>
</a>`
link.innerHTML = obj.render();
link = link.firstChild
link.addEventListener("mouseenter", e => itemMouseEnter(e))
searchResults.append(link)
Expand All @@ -80,7 +75,7 @@ window.addEventListener('load', () => {
updateSelectedItem(0)
} else {
const label = document.createElement("p")
label.className = "jenkins-command-center__info"
label.className = "jenkins-command-palette__info"
label.innerHTML = "<span>" + i18n.dataset.noResultsFor.escapeHTML() + "</span> " + e.target.value.escapeHTML()
searchResults.append(label)
}
Expand Down Expand Up @@ -142,15 +137,6 @@ window.addEventListener('load', () => {
commandPalette.close();
}

// Group suggestions by 'category' field into map
function groupByKey(array, key) {
return array
.reduce((hash, obj) => {
if (obj[key] === undefined) return hash
return Object.assign(hash, {[obj[key]]: (hash[obj[key]] || []).concat(obj)})
}, {})
}

function itemMouseEnter(item) {
let hoveredItems = document.querySelector("." + hoverClass)
if (hoveredItems) {
Expand Down
10 changes: 10 additions & 0 deletions war/src/main/js/components/command-palette/helpers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// Group suggestions by 'category' field into map
function groupByKey(array, key) {
return array
.reduce((hash, obj) => {
if (obj[key] === undefined) return hash
return Object.assign(hash, {[obj[key]]: (hash[obj[key]] || []).concat(obj)})
}, {})
}

export default {groupByKey: groupByKey};
35 changes: 35 additions & 0 deletions war/src/main/js/components/command-palette/models.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import * as Symbols from "./symbols";

class Result {
constructor(icon, label, description, category) {
this.icon = icon;
this.label = label;
this.description = description;
this.category = category;
console.log(this.icon)
}
render() {
return `<button class="jenkins-command-palette__results__item">
<div class="jenkins-command-palette__results__item__icon">${this.icon}"}</div>
${this.label}
${this.description ? `<span class="jenkins-command-palette__results__item__description">${this.description}</span>` : ``}
${Symbols.CHEVRON_RIGHT}
</button>`
}
}

export class LinkResult extends Result {
constructor(icon, label, description, category, url, isExternal) {
super(icon, label, description, category);
this.url = url;
this.isExternal = isExternal;
}
render() {
return `<a class="jenkins-command-palette__results__item" href="${this.url}">
<div class="jenkins-command-palette__results__item__icon">${this.icon ? `${this.icon.svg ? this.icon.svg : `<img src="${this.icon.url}" alt="" />`}` : ``}</div>
${this.label}
${this.description ? `<span class="jenkins-command-palette__results__item__description">${this.description}</span>` : ``}
${this.isExternal ? Symbols.EXTERNAL_LINK : Symbols.CHEVRON_RIGHT}
</a>`
}
}
13 changes: 13 additions & 0 deletions war/src/main/js/components/command-palette/services.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CommandPaletteHelpers from "./helpers";
import {LinkResult} from "./models";
import Search from "@/api/search";

async function getResults(query) {
const response = await Search.search(query);
return await response.json().then(data => {
const results = [...data["suggestions"]].map(e => new LinkResult(e.icon, e.name, e.description, e.category, e.url));
return CommandPaletteHelpers.groupByKey(results, "category");
});
}

export default {getResults: getResults}
3 changes: 3 additions & 0 deletions war/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.

Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
:root {
--command-center-backdrop: rgba(125, 125, 125, 0.9);
--command-center-background: rgba(255, 255, 255, 0.8);
--command-center-focus-color: var(--primary);
--command-center-drop-shadow: 0 0 60px rgba(5, 5, 20, 0.4);
--command-center-inset-shadow: inset 0 0 2px 2px rgba(white, 0.1);
--command-palette-backdrop: rgba(125, 125, 125, 0.9);
--command-palette-background: rgba(255, 255, 255, 0.8);
--command-palette-focus-color: var(--primary);
--command-palette-drop-shadow: 0 0 60px rgba(5, 5, 20, 0.4);
--command-palette-inset-shadow: inset 0 0 2px 2px rgba(white, 0.1);
}

@media (prefers-color-scheme: dark) {
:root {
--command-center-backdrop: rgba(20, 20, 25, 0.95);
--command-center-background: rgba(50, 50, 56, 0.7);
--command-center-focus-color: rgba(83, 193, 255, 0.5);
--command-center-drop-shadow: 0 0 60px rgba(0, 0, 15, 0.4);
--command-center-inset-shadow: inset 0 0 2px 2px rgba(240, 240, 255, 0.025);
--command-palette-backdrop: rgba(20, 20, 25, 0.95);
--command-palette-background: rgba(50, 50, 56, 0.7);
--command-palette-focus-color: rgba(83, 193, 255, 0.5);
--command-palette-drop-shadow: 0 0 60px rgba(0, 0, 15, 0.4);
--command-palette-inset-shadow: inset 0 0 2px 2px rgba(240, 240, 255, 0.025);
}
}

.jenkins-command-center__wrapper {
.jenkins-command-palette__wrapper {
background: none;
border: none;
filter: drop-shadow(var(--command-center-drop-shadow));
filter: drop-shadow(var(--command-palette-drop-shadow));
margin: 20vh auto;

&::backdrop {
backdrop-filter: saturate(1.5) contrast(0.75) brightness(0.45) blur(3px);
}
}

.jenkins-command-center {
.jenkins-command-palette {
position: relative;
width: 50vw;
min-width: 400px;
Expand All @@ -36,8 +36,8 @@
pointer-events: auto;

&__search {
background: var(--command-center-background);
box-shadow: 0 0 0 20px transparent, var(--command-center-inset-shadow);
background: var(--command-palette-background);
box-shadow: 0 0 0 20px transparent, var(--command-palette-inset-shadow);
margin-bottom: 1.5rem;
display: grid;
grid-template-columns: auto 1fr auto;
Expand Down Expand Up @@ -196,17 +196,17 @@
}

&:focus-within {
box-shadow: 0 0 0 5px var(--command-center-focus-color), var(--command-center-inset-shadow);
box-shadow: 0 0 0 5px var(--command-palette-focus-color), var(--command-palette-inset-shadow);
}
}

&__results-container {
display: flex;
flex-direction: column;
border-radius: 10px;
background: var(--command-center-background);
background: var(--command-palette-background);
backdrop-filter: saturate(2) blur(10px);
box-shadow: var(--command-center-inset-shadow);
box-shadow: var(--command-palette-inset-shadow);
height: 0;
transition: height 0.3s ease;
overflow: hidden;
Expand Down Expand Up @@ -296,17 +296,17 @@
display: flex;
align-items: center;
justify-content: center;
width: 18px;
height: 18px;
width: 1.4rem;
height: 1.4rem;
margin-right: 12.5px;
overflow: hidden;
pointer-events: none;
color: var(--primary);
color: var(--text-color);

svg,
img {
width: 18px;
height: 18px;
width: 1.4rem;
height: 1.4rem;
}
}

Expand Down
2 changes: 1 addition & 1 deletion war/src/main/less/styles.less
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ html {
@import './modules/breadcrumbs';
@import './modules/buttons';
@import './modules/buttons-temp';
@import "./modules/command-center";
@import "./modules/command-palette";
@import './modules/content-blocks';
@import './modules/icon-size';
@import './modules/icons';
Expand Down
5 changes: 3 additions & 2 deletions war/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ module.exports = (env, argv) => ({
path.join(__dirname, "src/main/js/config-tabbar.js"),
path.join(__dirname, "src/main/js/config-tabbar.less"),
],
"command-palette": [path.join(__dirname, "src/main/js/command-palette.js")],
"command-palette": [path.join(__dirname, "src/main/js/components/command-palette/command-palette.js")],
"sortable-drag-drop": [path.join(__dirname, "src/main/js/sortable-drag-drop.js")],
"section-to-tabs": [path.join(__dirname, "src/main/js/section-to-tabs.js")],
"filter-build-history": [path.join(__dirname, "src/main/js/filter-build-history.js")],
Expand Down Expand Up @@ -154,7 +154,8 @@ module.exports = (env, argv) => ({
}
},
resolve: {
alias:{
alias: {
'@': path.resolve(__dirname, 'src/main/js'),
// Needed to be able to register helpers at runtime
handlebars: 'handlebars/runtime',
},
Expand Down

0 comments on commit 684997d

Please sign in to comment.