fleet/website/assets/js/components/scrollable-tweets.component.js
Eric bdd9634c6a
Website: Update <scrollable-tweets> component (#9760)
Closes: https://github.com/fleetdm/fleet/issues/9656

Changes:
- Updated the <scrollable-tweets> compontent to:
  - update the current page indicator on mobile devices
- Handle scrolling to a page when the component has been scrolled
manually
  - increase the size of the page indicator on smaller screens
2023-02-08 20:04:56 -06:00

190 lines
9.2 KiB
JavaScript
Vendored
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* <scrollable-tweets>
* -----------------------------------------------------------------------------
* A horizontally scrolling row of tweets with an auto-updating page indicator
*
* @type {Component}
*
* -----------------------------------------------------------------------------
*/
parasails.registerComponent('scrollableTweets', {
// ╔═╗╦═╗╔═╗╔═╗╔═╗
// ╠═╝╠╦╝║ ║╠═╝╚═╗
// ╩ ╩╚═╚═╝╩ ╚═╝
props: [],
// ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗
// ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣
// ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝
data: function () {
return {
currentTweetPage: 0,
numberOfTweetCards: 6,
numberOfTweetPages: 0,
numberOfTweetsPerPage: 0,
tweetCardWidth: 0,
};
},
// ╦ ╦╔╦╗╔╦╗╦
// ╠═╣ ║ ║║║║
// ╩ ╩ ╩ ╩ ╩╩═╝
template: `
<div class="d-flex flex-column">
<div purpose="tweets" class="d-flex flex-row flex-nowrap">
<div purpose="tweet-card" class="card">
<div class="mb-4">
<a href="https://twitter.com/Uber"><img width="87" height="38" alt="Uber logo" src="/images/[email protected]"/></a>
</div>
<p class="pb-2 mb-1">Exciting. This is a team that listens to feedback.</p>
<div class="row px-3 pt-2">
<div>
<p class="font-weight-bold m-0">Erik Gomez</p>
<p class="m-0">Staff Software Engineer <a href="https://twitter.com/Uber">@Uber</a></p>
</div>
</div>
</div>
<div purpose="tweet-card" class="card">
<div class="mb-4">
<a href="https://twitter.com/Square"><img width="131" height="38" alt="Square logo" src="/images/[email protected]"/></a>
</div>
<p class="pb-2 mb-1">Mad props to how easy making a deploy pkg of Orbit was. I wish everyone made stuff that easy.</p>
<div class="row px-3 pt-2">
<div>
<p class="font-weight-bold m-0">Wesley Whetstone</p>
<p class="m-0">CPE <a href="https://twitter.com/Square">@Square</a></p>
</div>
</div>
</div>
<div purpose="tweet-card" class="card">
<div class="mb-4">
<a href="https://twitter.com/atlassian"><img width="162" height="20" alt="Atlassian logo" src="/images/[email protected]"/></a>
</div>
<p class="pb-2 mb-1"><a href="https://twitter.com/hashtag/fleet">#Fleet</a>s come a long way - to now being the top open-source <a href="https://twitter.com/hashtag/fleet">#osquery</a> manager. Just in the past 6 months.</p>
<div class="row px-3 pt-2">
<div>
<p class="font-weight-bold m-0">Brendan Shaklovitz</p>
<p class="m-0">Senior SRE <a href="https://twitter.com/atlassian">@Atlassian</a></p>
</div>
</div>
</div>
<div purpose="tweet-card" class="card">
<div class="mb-4">
<a href="https://twitter.com/osquery"><img width="140" height="36" alt="osquery logo" src="/images/[email protected]"/></a>
</div>
<p class="pb-2 mb-1">Its great to see the new release of Fleet containing some really cool new features that make <a href="https://twitter.com/osquery">@osquery</a> much more usable in practical environments. Im really impressed with the work that <a href="https://twitter.com/thezachw">@thezachw</a> and crew are doing at <a href="https://twitter.com/fleetctl">@fleetctl</a>.</p>
<div class="row px-3 pt-2">
<div>
<p class="font-weight-bold m-0">Mike Arpaia</p>
<p class="m-0">Creator of <a href="https://twitter.com/osquery">@osquery</a></p>
</div>
</div>
</div>
<div purpose="tweet-card" class="card">
<div class="mb-4">
<a href="https://twitter.com/Wayfair"><img width="136" height="32" alt="Wayfair logo" src="/images/[email protected]"/></a>
</div>
<p class="pb-2 mb-1"><a href="https://twitter.com/hashtag/osquery">#osquery</a> is one of the best tools out there and <a href="https://twitter.com/hashtag/fleetdm">#fleetdm</a> makes it even better. Highly recommend it if you want to monitor, detect and investigate threats on a scale and also for infra/sys admin.</p>
<p>I have used it on 15k servers and its really scalable.</p>
<div class="row px-3 pt-2">
<div>
<p class="font-weight-bold m-0">Ahmed Elshaer</p>
<p class="m-0">DFIR, Blue Teaming, SecOps <a href="https://twitter.com/Wayfair">@wayfair</a></p>
</div>
</div>
</div>
<div purpose="tweet-card" class="card">
<div class="mb-4">
<a href="https://twitter.com/comcast"><img width="107" height="38" alt="Comcast logo" src="/images/social-proof-logo-comcast-107x38.png"/></a>
</div>
<p class="pb-2 mb-1">With the power of osquery, you need a scalable & resilient platform to manage your workloads. Fleet is the "just right" open-source, enterprise grade solution.</p>
<div class="row px-3 pt-2">
<div>
<p class="font-weight-bold m-0">Abubakar Yousafzai</p>
<p class="m-0">Security Software Development & Engineering <a href="https://twitter.com/comcast">@Comcast</a></p>
</div>
</div>
</div>
</div>
<div purpose="" class="mx-auto">
<nav aria-label="..." >
<ul purpose="tweets-page-indicator" class="pagination pagination-sm" v-if="numberOfTweetPages > 1">
<li class="page-item" :class="[currentTweetPage === index ? 'selected' : '']" v-for="(pageNumber, index) in numberOfTweetPages" @click="scrollTweetsDivToPage(index)"></li>
</ul>
</nav>
</div>
</div>
`,
// ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗
// ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣
// ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝
beforeMount: function() {
//…
},
mounted: async function(){
await this.updateNumberOfTweetPages(); // Update the number of pages for the tweet page indicator.
const tweetsDiv = document.querySelector('div[purpose="tweets"]');
tweetsDiv.addEventListener('scroll', this.updatePageIndicator, {passive: true}); // Add a scroll event listener to update the tweet page indicator when a user scrolls the div.
window.addEventListener('resize', this.updateNumberOfTweetPages); // Add an event listener to update the number of tweet pages based on how many tweet cards can fit on the screen.
},
beforeDestroy: function() {
},
// ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗
// ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗
// ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝
methods: {
updateNumberOfTweetPages: async function() {
// Get the width of the first tweet card.
let firstTweetCardDiv = document.querySelector('div[purpose="tweet-card"]');
this.tweetCardWidth = firstTweetCardDiv.clientWidth + 16;
// Find out how may entire cards can fit on the screen.
this.numberOfTweetsPerPage = Math.floor(window.innerWidth / this.tweetCardWidth);
// Find out how many pages of tweet cards there will be.
this.numberOfTweetPages = Math.ceil(this.numberOfTweetCards / this.numberOfTweetsPerPage);
// Update the current page indicator.
this.updatePageIndicator();
await this.forceRender();
},
updatePageIndicator: function() {
// Get the tweets div.
let tweetsDiv = document.querySelector('div[purpose="tweets"]');
// Find out the width of a page of tweet cards
let tweetPageWidth;
if(this.numberOfTweetPages === 2 && this.numberOfTweetsPerPage > 3){
tweetPageWidth = this.tweetCardWidth;
} else {
tweetPageWidth = this.tweetCardWidth * this.numberOfTweetsPerPage;
}
// Set the maximum number of pages as the maximum value
let currentPage = Math.min(Math.round(tweetsDiv.scrollLeft / tweetPageWidth), (this.numberOfTweetPages - 1));
// Update the page indicator
this.currentTweetPage = currentPage;
},
scrollTweetsDivToPage: function(page) {
// Get the tweets div.
let tweetsDiv = document.querySelector('div[purpose="tweets"]');
// Find out the width of a page of tweet cards
let pageWidth = this.tweetCardWidth * this.numberOfTweetsPerPage;
// Figure out how much distance we're expecting to scroll.
let baseAmountToScroll = (page - this.currentTweetPage) * pageWidth;
// Find out the actual distance the div has been scrolled
let amountCurrentPageHasBeenScrolled = tweetsDiv.scrollLeft - (this.currentTweetPage * pageWidth);
// subtract the amount the current page has been scrolled from the baseAmountToScroll
let amountToScroll = baseAmountToScroll - amountCurrentPageHasBeenScrolled;
// Scroll the div to the specified 'page'
tweetsDiv.scrollBy(amountToScroll, 0);
},
}
});