Skip to content

Commit b56dc6b

Browse files
authored
Registry Refresher: UI changes, search updates & more (#3730)
1 parent 673a229 commit b56dc6b

File tree

727 files changed

+6628
-3187
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

727 files changed

+6628
-3187
lines changed

.cspell.yml

+1
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ words:
108108
- otep
109109
- otlp
110110
- overridable
111+
- packagist
111112
- Paixão
112113
- parentbased
113114
- Pavol

.textlintrc.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ filters:
99
allowlist:
1010
allow:
1111
# Don't check registry .yml file fields for language, repo and tags:
12-
- '/^(?:language|repo): .*$/m'
13-
- /^tags:(\s*-.+$)*/m
12+
- '/^\s*(?:language|repo|name|docs): .*$/m'
13+
- /^(?:tags):(\s*-.+$)*/m
1414
# Hugo template syntax:
1515
- /{{.*?}}/
1616
- /{{%.*?%}}/

assets/js/registrySearch.js

+136-127
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,37 @@
1-
let summaryInclude = 60;
2-
let fuseOptions = {
3-
shouldSort: true,
4-
includeMatches: true,
5-
threshold: 0.1,
6-
tokenize: true,
7-
location: 0,
8-
distance: 100,
9-
maxPatternLength: 32,
10-
minMatchCharLength: 1,
11-
keys: [
12-
{ name: 'title', weight: 0.8 },
13-
{ name: 'description', weight: 0.5 },
14-
{ name: 'tags', weight: 0.3 },
15-
{ name: 'categories', weight: 0.3 },
16-
],
1+
const miniSearchOptions = {
2+
fields: [
3+
'title',
4+
'description',
5+
'_key',
6+
'tags',
7+
'package.name',
8+
'license',
9+
'language',
10+
'registryType',
11+
], // fields to index for full-text search
12+
storeFields: ['title', '_key'], // fields to return with search results
13+
extractField: (document, fieldName) => {
14+
if (Array.isArray(document[fieldName])) {
15+
return document[fieldName].join(' ');
16+
}
17+
return fieldName.split('.').reduce((doc, key) => doc && doc[key], document);
18+
},
19+
searchOptions: {
20+
prefix: true,
21+
boost: {
22+
title: 4,
23+
tags: 3,
24+
description: 2,
25+
},
26+
fuzzy: 0.2,
27+
},
1728
};
1829

30+
const originalDocumentTitle = document.title;
31+
32+
let fetched = false;
33+
const miniSearch = new MiniSearch(miniSearchOptions);
34+
1935
// Get searchQuery for queryParams
2036
let pathName = window.location.pathname;
2137
let searchQuery = '';
@@ -27,14 +43,9 @@ parseUrlParams();
2743
if (pathName.includes('registry')) {
2844
// Run search or display default body
2945
if (searchQuery) {
30-
document.querySelector('#search-query').value = searchQuery;
31-
document.querySelector('#default-body').style.display = 'none';
3246
executeSearch(searchQuery);
3347
} else {
34-
let defaultBody = document.querySelector('#default-body');
35-
if (defaultBody.style.display === 'none') {
36-
defaultBody.style.display = 'block';
37-
}
48+
showBody();
3849
}
3950

4051
if (selectedLanguage !== 'all' || selectedComponent !== 'all') {
@@ -52,116 +63,22 @@ if (pathName.includes('registry')) {
5263
}
5364
updateFilters();
5465
}
55-
}
5666

57-
// Runs search through Fuse for fuzzy search
58-
function executeSearch(searchQuery) {
59-
fetch('/ecosystem/registry/index.json')
60-
.then((res) => res.json())
61-
.then((json) => {
62-
let fuse = new Fuse(json, fuseOptions);
63-
let results = fuse.search(searchQuery);
64-
65-
if (results.length > 0) {
66-
populateResults(results);
67-
} else {
68-
document.querySelector('#search-results').innerHTML +=
69-
'<p>No matches found</p>';
70-
}
67+
document.addEventListener('DOMContentLoaded', (event) => {
68+
let searchForm = document.getElementById('searchForm');
69+
searchForm.addEventListener('submit', function (evt) {
70+
evt.preventDefault();
71+
let val = document.getElementById('input-s').value;
72+
setInput('s', val);
73+
parseUrlParams();
74+
executeSearch(searchQuery);
7175
});
72-
}
7376

74-
// Populate the search results and render to the page
75-
function populateResults(results) {
76-
results.forEach((result, key) => {
77-
let contents = result.item.description;
78-
let snippet = '';
79-
let snippetHighlights = [];
80-
81-
if (fuseOptions.tokenize) {
82-
snippetHighlights.push(searchQuery);
83-
} else {
84-
result.matches.forEach((match) => {
85-
if (match.key === 'tags' || match.key === 'categories') {
86-
snippetHighlights.push(match.value);
87-
} else if (match.key === 'description') {
88-
start =
89-
match.indices[0][0] - summaryInclude > 0
90-
? match.indices[0][0] - summaryInclude
91-
: 0;
92-
end =
93-
match.indices[0][1] + summaryInclude < contents.length
94-
? match.indices[0][1] + summaryInclude
95-
: contents.length;
96-
snippet += contents.substring(start, end);
97-
snippetHighlights.push(
98-
match.value.substring(
99-
match.indices[0][0],
100-
match.indices[0][1] - mvalue.indices[0][0] + 1,
101-
),
102-
);
103-
}
104-
});
105-
}
106-
107-
if (snippet.length < 1 && contents.length > 0) {
108-
snippet += contents.substring(0, summaryInclude * 2);
109-
}
110-
111-
// Pull template from hugo template definition
112-
let templateDefinition = document.querySelector(
113-
'#search-result-template',
114-
).innerHTML;
115-
116-
// Replace values from template with search results
117-
let output = render(templateDefinition, {
118-
key: key,
119-
title: result.item.title,
120-
link: result.item.permalink,
121-
tags: result.item.tags,
122-
categories: result.item.categories,
123-
description: result.item.description,
124-
repo: result.item.repo,
125-
registryType: result.item.registryType,
126-
language: result.item.language,
127-
snippet: snippet,
128-
otVersion: result.item.otVersion,
77+
let searchInput = document.getElementById('input-s');
78+
searchInput.addEventListener('keyup', function (evt) {
79+
autoSuggest(evt.target.value);
12980
});
130-
document.querySelector('#search-results').innerHTML += output;
131-
});
132-
}
13381

134-
// Helper function to generate HTML for a search result
135-
function render(templateString, data) {
136-
let conditionalMatches, conditionalPattern, copy;
137-
conditionalPattern = /\$\{\s*isset ([a-zA-Z]*) \s*\}(.*)\$\{\s*end\s*}/g;
138-
//since loop below depends on re.lastInxdex, we use a copy to capture any manipulations whilst inside the loop
139-
copy = templateString;
140-
while (
141-
(conditionalMatches = conditionalPattern.exec(templateString)) !== null
142-
) {
143-
if (data[conditionalMatches[1]]) {
144-
//valid key, remove conditionals, leave contents.
145-
copy = copy.replace(conditionalMatches[0], conditionalMatches[2]);
146-
} else {
147-
//not valid, remove entire section
148-
copy = copy.replace(conditionalMatches[0], '');
149-
}
150-
}
151-
templateString = copy;
152-
153-
//now any conditionals removed we can do simple substitution
154-
let key, find, re;
155-
for (key in data) {
156-
find = '\\$\\{\\s*' + key + '\\s*\\}';
157-
re = new RegExp(find, 'g');
158-
templateString = templateString.replace(re, data[key]);
159-
}
160-
return templateString;
161-
}
162-
163-
if (pathName.includes('registry')) {
164-
document.addEventListener('DOMContentLoaded', (event) => {
16582
let languageList = document
16683
.getElementById('languageFilter')
16784
.querySelectorAll('.dropdown-item');
@@ -191,6 +108,98 @@ if (pathName.includes('registry')) {
191108
});
192109
}
193110

111+
function showBody() {
112+
document.title = originalDocumentTitle;
113+
document.querySelector('#search-results').innerHTML = '';
114+
let defaultBody = document.querySelector('#default-body');
115+
if (defaultBody.style.display === 'none') {
116+
defaultBody.style.display = 'block';
117+
}
118+
}
119+
120+
// Runs search through Fuse for fuzzy search
121+
function executeSearch(searchQuery) {
122+
if (searchQuery === '') {
123+
showBody();
124+
return;
125+
}
126+
127+
document.title = searchQuery + ' at ' + originalDocumentTitle;
128+
document.querySelector('#input-s').value = searchQuery;
129+
document.querySelector('#default-body').style.display = 'none';
130+
document.querySelector('#search-results').innerHTML = '';
131+
document.getElementById('search-loading').style.display = 'block';
132+
133+
const run = function (searchQuery) {
134+
// The 0-timeout is here if search is blocking, such that the "search loading" is rendered properly
135+
setTimeout(() => {
136+
let results = miniSearch.search(searchQuery);
137+
document.getElementById('search-loading').style.display = 'none';
138+
139+
if (results.length > 0) {
140+
populateResults(results);
141+
} else {
142+
document.querySelector('#search-results').innerHTML +=
143+
'<p>No matches found</p>';
144+
}
145+
}, 0);
146+
};
147+
148+
if (fetched) {
149+
run(searchQuery);
150+
} else {
151+
fetch('/ecosystem/registry/index.json')
152+
.then((res) => res.json())
153+
.then((json) => {
154+
fetched = true;
155+
miniSearch.addAll(json);
156+
run(searchQuery);
157+
});
158+
}
159+
}
160+
161+
function autoSuggest(value) {
162+
if (value === '') {
163+
return;
164+
}
165+
166+
const run = function (value) {
167+
const suggestions = miniSearch.autoSuggest(value, {
168+
// we only use title, otherwise we get strange suggestions, especially with description
169+
fields: ['title'],
170+
});
171+
const list = document.getElementById('search-suggestions');
172+
list.innerHTML = suggestions
173+
.map(({ suggestion }) => `<option>${suggestion}</option>`)
174+
.join('');
175+
};
176+
177+
if (fetched) {
178+
run(value);
179+
} else {
180+
fetch('/ecosystem/registry/index.json')
181+
.then((res) => res.json())
182+
.then((json) => {
183+
fetched = true;
184+
miniSearch.addAll(json);
185+
run(value);
186+
});
187+
}
188+
}
189+
190+
// Populate the search results and render to the page
191+
function populateResults(results) {
192+
document.querySelector('#search-results').innerHTML += results.reduce(
193+
(acc, result) => {
194+
return (
195+
acc +
196+
document.querySelector(`[data-registry-id="${result._key}"]`).outerHTML
197+
);
198+
},
199+
'',
200+
);
201+
}
202+
194203
function setInput(key, value) {
195204
document.getElementById(`input-${key}`).value = value;
196205
var queryParams = new URLSearchParams(window.location.search);

assets/scss/_registry.scss

+39
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
}
77
}
88

9+
@each $component, $color in $otel-registry-license-colors {
10+
&.badge-#{$component} {
11+
color: white;
12+
background-color: $color;
13+
}
14+
}
15+
916
&.badge-elixir {
1017
color: map-get($otel-component-colors, erlang);
1118
background-color: inherit;
@@ -28,3 +35,35 @@
2835
color: color-contrast($default-otel-badge-bg);
2936
background-color: $default-otel-badge-bg;
3037
}
38+
39+
.registry-entry {
40+
@extend .shadow;
41+
}
42+
43+
// fix me: the registry seems not to load the main.min.css with the extended
44+
// styles, so we need to define the styles here again.
45+
.highlight {
46+
margin: 1rem 0;
47+
padding: 0;
48+
position: relative;
49+
max-width: 95%;
50+
border: var(--bs-card-border-width) solid var(--bs-card-border-color);
51+
border-radius: var(--bs-card-border-radius);
52+
& pre {
53+
padding: 1rem;
54+
margin: 0;
55+
display: block;
56+
text-align: right;
57+
overflow-y: auto;
58+
& button.td-click-to-copy {
59+
position: absolute;
60+
color: #ced4da;
61+
border-radius: 3px;
62+
border-width: 0;
63+
background-color: inherit;
64+
box-shadow: 1px 1px #ced4da;
65+
right: 4px;
66+
top: 2px;
67+
}
68+
}
69+
}

assets/scss/_variables_project.scss

+7
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ $otel-component-colors: (
3333
'utilities': #2cd3b4,
3434
);
3535

36+
$otel-registry-license-colors: (
37+
'apache-20': #e83e8c,
38+
'bsd-2-clause': #8ce83e,
39+
'mit': #3e8ce8,
40+
'artistic-10-perl': #e8c83e,
41+
);
42+
3643
$primary: map-get($otel-colors, 'blue');
3744
$secondary: map-get($otel-colors, 'orange');
3845
$td-enable-google-fonts: false;

content/en/docs/languages/php/_index.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: >-
44
<img width="35" class="img-initial" src="/img/logos/32x32/PHP.svg" alt="PHP">
55
A language-specific implementation of OpenTelemetry in PHP.
66
weight: 21
7-
cSpell:ignore: mbstring opcache packagist
7+
cSpell:ignore: mbstring opcache
88
---
99

1010
{{% docs/languages/index-intro php /%}}

content/en/docs/languages/php/automatic.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Automatic Instrumentation
33
linkTitle: Automatic
44
weight: 30
55
# prettier-ignore
6-
cSpell:ignore: centos configurator democlass epel myapp packagist pecl phar remi unindented userland
6+
cSpell:ignore: centos configurator democlass epel myapp pecl phar remi unindented userland
77
---
88

99
Automatic instrumentation with PHP requires at least PHP 8.0, and the

0 commit comments

Comments
 (0)