Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
import template from '../templates/weighted-working-groups/working-group-block.mustache'
const defaultOptions = {
count: 1,
wrapperClass: ''
}
// Working groups with a weight of -1 will not be displayed.
const weights = {
default: -1,
'jakarta-ee': 1,
sdv: 20,
'cloud-development-tools': 30,
adoptium: 38,
oniro: 38,
'eclipse-ide': 44,
'internet-things-iot': 44,
aice: 50,
asciidoc: 50,
'edge-native': 50,
microprofile: 50,
openmobility: 50,
osgi: 50,
sparkplug: 50,
};
const fallbackLogos = {
sdv: '/images/collaborations/logos/software-defined-vehicle-fallback.png'
}
const removeDuplicates = (value, index, self) => self.indexOf(value) === index;
const getWeightedRandomIndex = (weightBuckets, categorizedArrayByWeight) => {
const largestWeight = Object.values(weights).sort().at(-1);
const randomNumber = Math.floor(Math.random() * largestWeight);
// Returns whatever number is the closest to a weight bucket
const closest = Object.values(weights).reduce((prev, curr) => {
return (Math.abs(curr - randomNumber) < Math.abs(prev - randomNumber) ? curr : prev);
})
const weightBucketSelectionIndex = weightBuckets.indexOf(closest);
const weightBucketSelection = weightBuckets[weightBucketSelectionIndex];
const selectionIndex = Math.floor(Math.random() * categorizedArrayByWeight[weightBucketSelection].length);
return categorizedArrayByWeight[weightBucketSelection][selectionIndex];
}
function getUniqueRandomWorkingGroups(workingGroupsCategorizedByWeight, weightBuckets, count) {
// Creates a set of selected working groups. This will omit duplicates.
let selectionSet = new Set();
while (selectionSet.size < count) {
const randomWorkingGroup = getWeightedRandomIndex(weightBuckets, workingGroupsCategorizedByWeight);
if (selectionSet.has(randomWorkingGroup)) continue;
selectionSet.add(randomWorkingGroup);
}
return Array.from(selectionSet);
}
async function getWeightedRandomWorkingGroups(count) {
const cachedWorkingGroups = JSON.parse(sessionStorage.getItem('weighted-working-groups'));
const isCached = cachedWorkingGroups != null;
// Only return the cached working groups if the count hasn't changed since last time run
if (isCached && cachedWorkingGroups.length === count) return cachedWorkingGroups;
const response = await fetch('https://membership.eclipse.org/api/working_groups');
const workingGroups = await response.json();
const weightBuckets = Object
.values(weights)
.filter(removeDuplicates);
// Create an object where the key is a bucket (or weight), and the value an array of working groups tied to that bucket
const weightBucketObject = weightBuckets.reduce((acc, bucket) => ({...acc, [bucket]: [] }), {})
const workingGroupsCategorizedByWeight = workingGroups.reduce((acc, wg) => {
const weight = weights[wg.alias] || weights.default;
acc[weight].push(wg);
return acc;
}, { ...weightBucketObject });
// Retrieves weighted random working groups and stores it in session storage cache
const randomWorkingGroups = getUniqueRandomWorkingGroups(workingGroupsCategorizedByWeight, weightBuckets, count);
sessionStorage.setItem('weighted-working-groups', JSON.stringify(randomWorkingGroups));
return randomWorkingGroups;
};
const matchHeightForLogos = (baseElement) => {
const imgElements = baseElement.querySelectorAll('.weighted-working-group-logo');
imgElements.forEach(el => {
el.addEventListener('load', () => {
$('.weighted-working-group-block-wrapper').matchHeight();
});
});
}
const getWorkingGroupLogo = ({ alias, logo } = workingGroup) => {
const fallbackLogo = fallbackLogos[alias];
if (logo === '') return fallbackLogo || '';
return logo;
}
(async function renderWeightedWorkingGroups() {
const element = document.querySelector('.eclipsefdn-weighted-working-groups');
if (!element) return;
const options = {
...defaultOptions,
...element.dataset,
count: +element.dataset.count
};
element.innerHTML = template({ isFetching: true, items: new Array(options.count) , wrapperClass: options.wrapperClass })
const workingGroups = await getWeightedRandomWorkingGroups(options.count);
const data = {
isFetching: false,
wrapperClass: options.wrapperClass,
items: workingGroups.map(wg => ({
title: wg.title,
logo: getWorkingGroupLogo(wg),
websiteUrl: wg.resources.website,
}))
};
element.innerHTML = template(data);
matchHeightForLogos(element);
})();