123 lines
3.3 KiB
JavaScript
123 lines
3.3 KiB
JavaScript
/*
|
|
* This JavaScript file was hand-crafted by a developer who doesn't normally
|
|
* write JavaScript and should not be considered indicative of how Scribd's
|
|
* proper web engineers write JavaScript.
|
|
*
|
|
* With that disclaimer out of the way...
|
|
*
|
|
* This file handles the fetching of jobs from Lever such that they can be
|
|
* dynamically inserted into different parts of the tech blog
|
|
*/
|
|
|
|
/*
|
|
* This API will return an list of departments which must then be filtered
|
|
* through to find the .postings under each
|
|
*/
|
|
const API_URL = 'https://api.lever.co/v0/postings/scribd?group=department&mode=json'
|
|
|
|
|
|
/*
|
|
* Everybody loves globals, this will make sure we don't hit the API more than
|
|
* we need to.
|
|
*/
|
|
window.jobsCache = {};
|
|
window.jobsFetched = false;
|
|
|
|
|
|
/**
|
|
* Fetch the jobs from the Lever API and cache them into a page-wide global
|
|
*
|
|
* This will always return a Promise, even when the cache is hit
|
|
*/
|
|
function fetchJobs() {
|
|
if (window.jobsFetched) {
|
|
// Whoa there cowboy, only hit their API once per page
|
|
return Promise.resolve(window.jobsCache);
|
|
}
|
|
|
|
return fetch(API_URL)
|
|
.then(async (response) => {
|
|
const departments = await response.json();
|
|
/*
|
|
* Since this is the tech blog, we're only pulling a couple of
|
|
* departments
|
|
*/
|
|
departments
|
|
.filter(d => ['Engineering', 'Data Science', 'Design'].includes(d.title))
|
|
.forEach((department) => {
|
|
department.postings.forEach((posting) => {
|
|
const team = posting.categories.team;
|
|
if (!window.jobsCache[team]) {
|
|
window.jobsCache[team] = [];
|
|
}
|
|
window.jobsCache[team].push(posting);
|
|
});
|
|
});
|
|
window.jobsFetched = true;
|
|
return window.jobsCache;
|
|
})
|
|
.catch((err) => {
|
|
console.error(`Failed to fetch the jobs from Lever, ruh roh ${err}`);
|
|
});
|
|
}
|
|
|
|
|
|
/**
|
|
* Render the available jobs into the given element
|
|
*
|
|
* team is an optional parameter and will filter the results to just that team.
|
|
* Send null to receive all engineering jobs
|
|
*
|
|
* Use the randomLimit parameter to receive a random slice of the jobs limited
|
|
* to the number passed through
|
|
*/
|
|
function renderJobs(elem, team, randomLimit) {
|
|
if (!elem) {
|
|
console.error("Cannot renderJobs() to an empty element");
|
|
return;
|
|
}
|
|
|
|
fetchJobs().then((jobs) => {
|
|
let toRender = (team ? jobs[team] : Object.values(jobs).flat());
|
|
|
|
/*
|
|
* Sometimes we won't have any jobs for a team
|
|
*/
|
|
if (!toRender) {
|
|
return;
|
|
}
|
|
|
|
if (randomLimit) {
|
|
shuffleArray(toRender);
|
|
toRender = toRender.slice(0, randomLimit);
|
|
}
|
|
|
|
toRender.forEach((job) => {
|
|
const li = document.createElement('li');
|
|
li.className = 'card theme-midnight';
|
|
li.innerHTML = `
|
|
<div class="card__body">
|
|
<h5 class="mb-1 clamp-2">
|
|
<a href="${job.hostedUrl}" target="_blank" class="stretched-link link-text-color">${job.text}</a>
|
|
</h5>
|
|
<p class="m-0 fs-md monospace text-truncate">${job.categories.location}</p>
|
|
</div>
|
|
`;
|
|
elem.appendChild(li);
|
|
});
|
|
|
|
|
|
});
|
|
}
|
|
|
|
|
|
/*
|
|
* Nice shuffle method courtesy of https://stackoverflow.com/a/12646864
|
|
*/
|
|
function shuffleArray(array) {
|
|
for (let i = array.length - 1; i > 0; i--) {
|
|
const j = Math.floor(Math.random() * (i + 1));
|
|
[array[i], array[j]] = [array[j], array[i]];
|
|
}
|
|
}
|