Skip to content

Commit 10b1a69

Browse files
committed
Creation of patterns browser v2
1 parent 2f8abaf commit 10b1a69

4 files changed

Lines changed: 263 additions & 72 deletions

File tree

layouts/partials/menu-patterns-browser.html

Lines changed: 4 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,7 @@ <h2 class="accordion-header" id="typeHeading">
2020
<div class="pf-c-accordion__expanded-content-body">
2121
<a href="/learn/about-pattern-tiers-types/">What do these tiers mean?</a>
2222
<div class="pf-c-select__menu-group">
23-
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-patterntype">
24-
<label class="pf-c-check pf-c-select__menu-item" for="type:maintained">
25-
<input class="pf-c-check__input" type="checkbox" onclick="filterSelection(this.id)" id="type:maintained" name="maintained"/>
26-
<span class="pf-c-check__label">Maintained</span>
27-
</label>
28-
<label class="pf-c-check pf-c-select__menu-item" for="type:tested">
29-
<input class="pf-c-check__input" type="checkbox" onclick="filterSelection(this.id)" id="type:tested" name="tested"/>
30-
<span class="pf-c-check__label">Tested</span>
31-
</label>
32-
<label class="pf-c-check pf-c-select__menu-item" for="type:sandbox">
33-
<input class="pf-c-check__input" type="checkbox" onclick="filterSelection(this.id)" id="type:sandbox" name="sandbox"/>
34-
<span class="pf-c-check__label">Sandbox</span>
35-
</label>
23+
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-patterntype" id="TiersItems">
3624
</fieldset>
3725
</div>
3826
</div>
@@ -56,13 +44,7 @@ <h2 class="accordion-header" id="industriesHeading">
5644
<div id="collapseIndustries" class="pf-c-accordion__expanded-content collapse" aria-labelledby="industriesHeading" data-bs-parent="#patternsAccordionNav">
5745
<div class="pf-c-accordion__expanded-content-body">
5846
<div class="pf-c-select__menu-group">
59-
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-industry">
60-
{{ range $name, $taxonomy := .Site.Taxonomies.industries }}
61-
<label class="pf-c-check pf-c-select__menu-item" for="industries:{{- $name | urlize -}}">
62-
<input class="pf-c-check__input" type="checkbox" id="industries:{{- $name | urlize -}}" onclick="filterSelection(this.id)" name="{{- $name | humanize | title -}}"/>
63-
<span class="pf-c-check__label">{{- $name | humanize | title -}}</span>
64-
</label>
65-
{{ end }}
47+
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-industry" id="IndustriesItems">
6648
</fieldset>
6749
</div>
6850
</div>
@@ -86,13 +68,7 @@ <h2 class="accordion-header" id="rhProductHeading">
8668
<div id="collapseRhProducts" class="pf-c-accordion__expanded-content collapse" aria-labelledby="productHeading" data-bs-parent="#patternsAccordionNav">
8769
<div class="pf-c-accordion__expanded-content-body">
8870
<div class="pf-c-select__menu-group">
89-
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-rh-products">
90-
{{ range $name, $taxonomy := .Site.Taxonomies.rh_products }}
91-
<label class="pf-c-check pf-c-select__menu-item" for="rh_products:{{- $name | urlize -}}">
92-
<input class="pf-c-check__input" type="checkbox" id="rh_products:{{- $name | urlize -}}" onclick="filterSelection(this.id)" name="{{ $taxonomy.Page.Title }}"/>
93-
<span class="pf-c-check__label wrappable">{{ $taxonomy.Page.Title }}</span>
94-
</label>
95-
{{ end }}
71+
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-rh-products" id="RhProductsItems">
9672
</fieldset>
9773
</div>
9874
</div>
@@ -116,13 +92,7 @@ <h2 class="accordion-header" id="otherProductHeading">
11692
<div id="collapseOtherProducts" class="pf-c-accordion__expanded-content collapse" aria-labelledby="otherProductHeading" data-bs-parent="#patternsAccordionNav">
11793
<div class="pf-c-accordion__expanded-content-body">
11894
<div class="pf-c-select__menu-group">
119-
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-RHproducts">
120-
{{ range $name, $taxonomy := .Site.Taxonomies.other_products }}
121-
<label class="pf-c-check pf-c-select__menu-item" for="other_products:{{- $name | urlize -}}">
122-
<input class="pf-c-check__input" type="checkbox" id="other_products:{{- $name | urlize -}}" onclick="filterSelection(this.id)" name="{{ $taxonomy.Page.Title }}"/>
123-
<span class="pf-c-check__label wrappable">{{ $taxonomy.Page.Title }}</span>
124-
</label>
125-
{{ end }}
95+
<fieldset class="pf-c-select__menu-fieldset" aria-labelledby="select-checkbox-expanded-selected-group-otherproducts" id="OtherProductsItems">
12696
</fieldset>
12797
</div>
12898
</div>

layouts/partials/patterns-browser.html

Lines changed: 22 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -25,45 +25,35 @@ <h1 class="pf-c-title pf-m-4xl">
2525
{{ $patterns := where $.Pages "Section" "patterns"}}
2626
<div class="pf-l-stack pf-m-gutter">
2727
<div class="pf-l-stack__item pf-u-text-align-right pattern-count-style">
28-
<span id="pattern-count">{{- len $patterns -}}</span> of {{ len $patterns }} patterns displayed
28+
<label class="pf-c-form__label" for="form-vertical-name">
29+
<span class="pf-c-form__label-text">Sort:</span>
30+
</label>
31+
<select
32+
class
33+
id="select-pattern-sort"
34+
name="select-pattern-sort"
35+
aria-label="Selector for pattern sort"
36+
onchange="filterSelection()"
37+
>
38+
<option value="atoz" selected>A to Z</option>
39+
<option value="ztoa">Z to A</option>
40+
<option value="newest">Newest</option>
41+
<option value="oldest">Oldest</option>
42+
</select>
43+
</div>
44+
<div class="pf-l-stack__item pf-u-text-align-right pattern-count-style" id="pattern-counter">
45+
</div>
46+
<div class="pf-l-stack__item" id="patternLoaderSpinner">
2947
</div>
3048
<div class="pf-l-stack__item">
31-
<div class="pf-l-gallery pf-m-gutter" style="--pf-l-gallery--GridTemplateColumns--min: 300px;">
32-
{{ range $pattern := $patterns.ByTitle }}
33-
{{ $data := newScratch }}
34-
{{ $data.Set "tags" slice }}
35-
{{ $params := .Params }}
36-
{{ range $taxonomyname, $taxonomy := .Site.Taxonomies }}
37-
38-
{{ if isset $params $taxonomyname }}
39-
{{ range $term := $pattern.Param $taxonomyname }}
40-
{{ $taglist := $data.Get "tags" }}
41-
{{ $taglist := $taglist | append (string (printf "%s:%s" $taxonomyname ($term | urlize) | printf "%s" )) }}
42-
{{ $data.Set "tags" $taglist }}
43-
{{ end }}
44-
45-
{{ end }}
46-
{{ end }}
47-
{{ $taglist := $data.Get "tags" }}
48-
{{ $validated := .Param "tier" }}
49-
{{ if (eq $validated "maintained" ) }}
50-
{{ .Scratch.Set "patterntype" "type:maintained" }}
51-
{{ else if (eq $validated "tested" ) }}
52-
{{ .Scratch.Set "patterntype" "type:tested" }}
53-
{{ else }}
54-
{{ .Scratch.Set "patterntype" "type:sandbox" }}
55-
{{ end }}
56-
{{ $patterntype := .Scratch.Get "patterntype" }}
57-
<div class="pf-l-gallery__item filterDiv" tag-data="{{ delimit $taglist " " }} {{ $patterntype }}" style="display: grid;">
58-
{{ .Render "summary-with-image" }}
59-
</div>
60-
{{ end }}
49+
<div class="pf-l-gallery pf-m-gutter" style="--pf-l-gallery--GridTemplateColumns--min: 300px;" id="patternCards">
6150
</div>
6251
</div>
6352
</div>
6453
</div>
6554
</div>
66-
<script src="{{ "js/filter.js" | relURL }}"></script>
55+
<div id="debug"></div>
56+
<script src="{{ "js/patterns-browser-v2.js" | relURL }}"></script>
6757
</section>
6858
{{ partial "footer.html" . }}
6959
</main>

layouts/patterns/list.json.json

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,40 @@
11
{{- if (eq .RelPermalink "/patterns/") }}
2+
3+
{{/* Patterns */}}
24
{{- $patterns := where $.Pages "Section" "patterns"}}
3-
{{- $patterns_len := $patterns | len }}
4-
{{- $pattern_list := slice }}
5-
{{- range $index, $pattern := $patterns.ByTitle }}
6-
{{- $pattern_list = $pattern_list | append (dict $pattern.Title $pattern.Params) }}
7-
{{- end }}
8-
{{- $pattern_list | jsonify }}
5+
{{- $pattern_list := slice }}
6+
{{- range $index, $pattern := $patterns.ByTitle }}
7+
{{- $object := dict "Name" $pattern.LinkTitle "Link" $pattern.RelPermalink "Params" $pattern.Params -}}
8+
{{- $pattern_list = $pattern_list | append $object -}}
9+
{{- end }}
10+
11+
{{/* Red Hat Products */}}
12+
{{- $rh_products := .Site.Taxonomies.rh_products }}
13+
{{- $rh_products_list := slice }}
14+
{{- range $index, $rh_product := $rh_products.Alphabetical }}
15+
{{- $rh_products_list = $rh_products_list | append (dict "Name" $rh_product.Name "LinkTitle" $rh_product.Page.LinkTitle) }}
16+
{{- end }}
17+
18+
{{/* Other Products */}}
19+
{{- $other_products := .Site.Taxonomies.other_products }}
20+
{{- $other_products_list := slice }}
21+
{{- range $index, $other_product := $other_products.Alphabetical }}
22+
{{- $other_products_list = $other_products_list | append (dict "Name" $other_product.Name "LinkTitle" $other_product.Page.LinkTitle) }}
23+
{{- end }}
24+
25+
{{/* Industries */}}
26+
{{- $industries := .Site.Taxonomies.industries }}
27+
{{- $industries_list := slice }}
28+
{{- range $index, $industry := $industries.Alphabetical }}
29+
{{- $industries_list = $industries_list | append (dict "Name" $industry.Name "LinkTitle" $industry.Page.LinkTitle) }}
30+
{{- end }}
31+
32+
{{/* Tiers */}}
33+
{{- $tiers_list := slice -}}
34+
{{- $tiers_list = $tiers_list | append (dict "Name" "maintained" "LinkTitle" "Maintained") }}
35+
{{- $tiers_list = $tiers_list | append (dict "Name" "tested" "LinkTitle" "Tested") }}
36+
{{- $tiers_list = $tiers_list | append (dict "Name" "sandbox" "LinkTitle" "Sandbox") }}
37+
38+
{{- $filter_categories := dict "rh_products" $rh_products_list "other_products" $other_products_list "industries" $industries_list "tier" $tiers_list -}}
39+
{{- dict "patterns" $pattern_list "filter_categories" $filter_categories | jsonify }}
940
{{- end }}

static/js/patterns-browser-v2.js

Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
async function getData() {
2+
const url = "/patterns/index.json";
3+
try {
4+
const response = await fetch(url);
5+
if (!response.ok) {
6+
throw new Error(`Response status: ${response.status}`);
7+
}
8+
const json = await response.json();
9+
return json;
10+
} catch (error) {
11+
console.error(error.message);
12+
}
13+
}
14+
15+
function sleep (time) {
16+
return new Promise((resolve) => setTimeout(resolve, time));
17+
}
18+
19+
function cleanString(string) {
20+
return string.replace(/ /g, "-")
21+
}
22+
23+
function capitalizeFirstLetter(string) {
24+
return string[0].toUpperCase() + string.slice(1);
25+
}
26+
27+
function sortAtoZ(a, b){
28+
const nameA = a.Name.toUpperCase()
29+
const nameB = b.Name.toUpperCase()
30+
if (nameA < nameB) {
31+
return -1;
32+
}
33+
if (nameA > nameB) {
34+
return 1;
35+
}
36+
return 0;
37+
}
38+
39+
function sortDate(a, b){
40+
if (a.Params.date != undefined) {
41+
var dateA = new Date(a.Params.date)
42+
} else {
43+
var dateA = new Date("2000-01-01T00:00:00Z");
44+
};
45+
if (b.Params.date != undefined) {
46+
var dateB = new Date(b.Params.date)
47+
} else {
48+
var dateB = new Date("2000-01-01T00:00:00Z");
49+
};
50+
if (dateA < dateB) {
51+
return -1;
52+
}
53+
if (dateA > dateB) {
54+
return 1;
55+
}
56+
return 0;
57+
}
58+
59+
function renderSpinner() {
60+
return '<div class="pf-l-bullseye">' +
61+
'<div class="pf-l-bullseye__item">' +
62+
'<svg class="pf-c-spinner" role="progressbar" viewBox="0 0 100 100" aria-label="Loading..." >' +
63+
'<circle class="pf-c-spinner__path" cx="50" cy="50" r="45" fill="none" />' +
64+
'</svg>' +
65+
'</div>' +
66+
'</div>';
67+
}
68+
69+
function renderFilterItem(type, name, linkTitle) {
70+
var filterItem = '<label class="pf-c-check pf-c-select__menu-item" for="' + type + ':' + cleanString(name) + '">' +
71+
'<input class="pf-c-check__input" type="checkbox" id="' + type + ':' + cleanString(name) + '"' + 'onclick="filterSelection()" name="' + linkTitle + '"/>' +
72+
'<span class="pf-c-check__label wrappable">' + linkTitle + '</span>'+
73+
'</label>';
74+
return filterItem;
75+
}
76+
77+
function renderFilter(elementId, filterType, filterData) {
78+
for (item = 0; item < filterData.length; item++) {
79+
const element = document.getElementById(elementId);
80+
element.innerHTML += renderFilterItem(filterType, filterData[item].Name, filterData[item].LinkTitle);
81+
};
82+
}
83+
84+
function renderLabel(tier) {
85+
if (tier != undefined) {
86+
if (tier == "maintained") { var color = "green" }
87+
else if (tier == "tested") { var color = "blue" }
88+
else if (tier == "sandbox") { var color = "orange" };
89+
var renderedLabel = '<span class="pf-c-label pf-m-' + color +'">' +
90+
'<span class="pf-c-label__content">' +
91+
'<img src="/images/pattern-tier-' + tier + '.png" alt="' + capitalizeFirstLetter(tier) + '" width="16" height="16" class="custom-pattern-icon"/>' +
92+
capitalizeFirstLetter(tier) +
93+
'</span>' +
94+
'</span>';
95+
return renderedLabel;
96+
} else {
97+
return "";
98+
};
99+
}
100+
101+
function renderCard(pattern) {
102+
var renderCard = '<div class="pf-l-gallery__item" style="display: grid;">' +
103+
'<div class="pf-c-card" style="text-align: left; --pf-c-card__title--FontSize: 1rem; --pf-c-card__body--FontSize: 0.95rem;">' +
104+
'<div class="pf-c-card__title">' +
105+
'<a href="' + pattern.Link +'">' +
106+
pattern.Name +
107+
'</a>' +
108+
'</div>' +
109+
'<div class="pf-c-card__body">' +
110+
pattern.Params.summary +
111+
'</div>' +
112+
'<div class="pf-c-card__footer">' +
113+
renderLabel(pattern.Params.tier) +
114+
'</div>' +
115+
'</div>' +
116+
'</div>';
117+
return renderCard;
118+
}
119+
120+
function renderFilteredCards(patterns, filter_categories) {
121+
const element = document.getElementById("patternCards");
122+
const patternLoaderSpinner = document.getElementById("patternLoaderSpinner");
123+
element.innerHTML = "";
124+
patternLoaderSpinner.innerHTML = renderSpinner();
125+
var filter = new Object();
126+
var filteredPatterns = [];
127+
var sortValue = document.getElementById("select-pattern-sort");
128+
for (const [category, terms] of Object.entries(filter_categories)) {
129+
for (item = 0; item < terms.length; item++) {
130+
var checkboxId = category + ":" + cleanString(terms[item].Name);
131+
var checkbox = document.getElementById(checkboxId);
132+
if (checkbox.checked) {
133+
if (filter[category] == undefined) { filter[category] = [] };
134+
filter[category].push(terms[item].LinkTitle);
135+
};
136+
};
137+
};
138+
for (item = 0; item < patterns.length; item++) {
139+
var checksPassed = new Object();
140+
for (const [category, terms] of Object.entries(filter)) {
141+
if (typeof(patterns[item].Params[category]) == "string") {
142+
for (termId = 0; termId < terms.length; termId++) {
143+
if (terms[termId].toLowerCase() == patterns[item].Params[category].toLowerCase()) {
144+
checksPassed[category] = true;
145+
}
146+
}
147+
} else if (typeof(patterns[item].Params[category]) == "object" && patterns[item].Params[category] != null) {
148+
var patternTerms = patterns[item].Params[category].map(v => v.toLowerCase());
149+
var filterTerms = terms.map(v => v.toLowerCase());
150+
if(filterTerms.every(r => patternTerms.includes(r))) {
151+
checksPassed[category] = true;
152+
};
153+
};
154+
};
155+
var patternPassed = true;
156+
for (const [category, terms] of Object.entries(filter)) {
157+
if (checksPassed[category] != true) {
158+
patternPassed = false;
159+
};
160+
};
161+
if (patternPassed == true) { filteredPatterns.push(patterns[item]); };
162+
};
163+
if (sortValue.value == "atoz") {
164+
filteredPatterns.sort(sortAtoZ);
165+
} else if (sortValue.value == "ztoa") {
166+
filteredPatterns.sort(sortAtoZ);
167+
filteredPatterns.reverse();
168+
} else if (sortValue.value == "oldest") {
169+
filteredPatterns.sort(sortDate);
170+
} else if (sortValue.value == "newest") {
171+
filteredPatterns.sort(sortDate);
172+
filteredPatterns.reverse();
173+
};
174+
patternLoaderSpinner.innerHTML = "";
175+
for (item = 0; item < filteredPatterns.length; item++) {
176+
const element = document.getElementById("patternCards");
177+
element.innerHTML += renderCard(filteredPatterns[item]);
178+
};
179+
var totalPatternsCount = patterns.length
180+
var filteredPatternsCount = filteredPatterns.length
181+
const counter = document.getElementById("pattern-counter");
182+
counter.innerHTML = filteredPatternsCount + " of " + totalPatternsCount + " patterns displayed";
183+
}
184+
185+
function filterSelection(filter) {
186+
// Declaring variables
187+
const patternsData = getData()
188+
patternsData.then(output => {
189+
renderFilteredCards(output.patterns, output.filter_categories)
190+
});
191+
}
192+
193+
const patternsData = getData()
194+
patternsData.then(output => {
195+
renderFilter("TiersItems", "tier", output.filter_categories.tier);
196+
renderFilter("IndustriesItems", "industries", output.filter_categories.industries);
197+
renderFilter("RhProductsItems", "rh_products", output.filter_categories.rh_products);
198+
renderFilter("OtherProductsItems", "other_products", output.filter_categories.other_products);
199+
renderFilteredCards(output.patterns, output.filter_categories)
200+
});

0 commit comments

Comments
 (0)