diff --git a/handbook/company/testimonials.yml b/handbook/company/testimonials.yml index 11837fc653..aebe6c3f55 100644 --- a/handbook/company/testimonials.yml +++ b/handbook/company/testimonials.yml @@ -1,94 +1,140 @@ # - # quote: - required -# quoteAuthorName: - required +# quoteAuthorName: required # quoteAuthorJobTitle: required -# quoteAuthorSocialHandle: +# quoteLinkUrl: required +# quoteAuthorProfileImageFilename: required # quoteImageFilename: -# quoteLinkUrl: - required if there is an image # youtubeVideoUrl: +#. productCategories: [Endpoint operations, Vulnerability management, Device management] - quote: The visibility down into the assets covered by the agent is phenomenal. Fleet has become the central source for a lot of things. quoteAuthorName: Andre Shields + quoteAuthorProfileImageFilename: testimonial-author-andre-shields-48x48@2x.png + quoteLinkUrl: https://www.linkedin.com/in/andre-shields/ quoteAuthorJobTitle: Cybersecurity Security Engineer, Vulnerability Management youtubeVideoUrl: https://www.youtube.com/watch?v=siXy9aanOu4 + productCategories: [Endpoint operations, Vulnerability management] - quote: I love the steady and consistent delivery of features that help teams work how they want to work, not how your product dictates they work. ❤️ quoteImageFilename: social-proof-linktree-logo-119x24@2x.png - quoteLinkUrl: https://twitter.com/Linktree_ + quoteLinkUrl: https://www.linkedin.com/in/danielgrzelak/ quoteAuthorName: Daniel Grzelak - quoteAuthorJobTitle: CISO of - quoteAuthorSocialHandle: Linktree + quoteAuthorProfileImageFilename: testimonial-author-daniel-grzelak-48x48@2x.png + quoteAuthorJobTitle: Principle red team engineer + productCategories: [Endpoint operations, Vulnerability management, Device management] - quote: We can build it exactly the way we want it. Which is just not possible on other platforms. quoteAuthorName: Austin Anderson + quoteAuthorProfileImageFilename: testimonial-author-austin-anderson-48x48@2x.png quoteAuthorJobTitle: Cybersecurity team senior manager + quoteLinkUrl: https://www.linkedin.com/in/austin-anderson-73172185/ youtubeVideoUrl: https://www.youtube.com/watch?v=G5Ry_vQPaYc + productCategories: [Endpoint operations, Vulnerability management] - quote: Exciting. This is a team that listens to feedback. quoteImageFilename: social-proof-logo-uber-87x38@2x.png - quoteLinkUrl: https://twitter.com/Uber + quoteLinkUrl: https://www.linkedin.com/in/eriknicolasgomez/ quoteAuthorName: Erik Gomez - quoteAuthorJobTitle: Staff Software Engineer - quoteAuthorSocialHandle: "@Uber" + quoteAuthorProfileImageFilename: testimonial-author-erik-gomez-48x48@2x.png + quoteAuthorJobTitle: Senior Staff Security Engineer at Uber + productCategories: [Endpoint operations, Vulnerability management, Device management] - quote: Context is king for device data, and Fleet provides a way to surface that information to our other teams and partners. quoteAuthorName: Nick Fohs + quoteAuthorProfileImageFilename: testimonial-author-nick-fohs-24x24@2x.png + quoteLinkUrl: https://www.linkedin.com/in/nickfohs/ quoteAuthorJobTitle: Systems and infrastructure manager youtubeVideoUrl: https://www.youtube.com/watch?v=fs5ULAR4e4A + productCategories: [Endpoint operations, Vulnerability management, Device management] - quote: Keeping up with the latest issues in endpoint security is a never-ending task, because engineers have to regularly ensure every laptop and server is still sufficiently patched and securely configured. The problem is, software vendors release new versions all the time, and no matter how much you lock it down, end users find ways to change things. - quoteImageFilename: social-proof-logo-lyft-145x103@2x.png - quoteLinkUrl: https://twitter.com/lyft + quoteImageFilename: logo-lyft-46x32@2x.png + quoteLinkUrl: https://www.linkedin.com/in/nwaisman/ quoteAuthorName: Nico Waisman - quoteAuthorJobTitle: CISO of - quoteAuthorSocialHandle: Lyft + quoteAuthorProfileImageFilename: testimonial-author-nico-waisman-48x48@2x.png + quoteAuthorJobTitle: CISO of Lyft + productCategories: [Endpoint operations, Vulnerability management] - quote: Fleet has been highly effective for our needs. We appreciate your team for always being so open to hearing our feedback. quoteAuthorName: Kenny Botelho - quoteAuthorSocialHandle: "@kennyb-222" - quoteLinkUrl: https://github.com/kennyb-222 + quoteAuthorProfileImageFilename: testimonial-author-kenny-botelho-48x48@2x.png + quoteAuthorJobTitle: Client Platform IT Engineer / Leader + quoteLinkUrl: https://www.linkedin.com/in/kennybotelho/ + productCategories: [Endpoint operations, Device management] - quote: Mad props to how easy making a deploy pkg of Orbit was. I wish everyone made stuff that easy. - quoteImageFilename: social-proof-logo-square-131x38@2x.png - quoteLinkUrl: https://twitter.com/Square + quoteImageFilename: logo-stripe-57x24@2x.png quoteAuthorName: Wesley Whetstone - quoteAuthorJobTitle: CPE - quoteAuthorSocialHandle: "@Square" + quoteAuthorProfileImageFilename: testimonial-author-wes-whetstone-48x48@2x.png + quoteLinkUrl: https://www.linkedin.com/in/jckwhet/ + quoteAuthorJobTitle: Staff CPE at Stripe + productCategories: [Endpoint operations, Vulnerability management, Device management] - quote: "#Fleet’s come a long way - to now being the top open-source #osquery manager. Just in the past 6 months." quoteImageFilename: social-proof-logo-atlassian-162x20@2x.png - quoteLinkUrl: https://twitter.com/atlassian + quoteLinkUrl: https://www.linkedin.com/in/bshak/ quoteAuthorName: Brendan Shaklovitz + quoteAuthorProfileImageFilename: testimonial-author-brendan-shaklovitz-48x48@2x.png quoteAuthorJobTitle: Senior SRE - quoteAuthorSocialHandle: "@Atlassian" + productCategories: [Endpoint operations] - quote: It’s great to see the new release of Fleet containing some really cool new features that make @osquery much more usable in practical environments. I’m really impressed with the work that @thezachw and crew are doing at @fleetctl. quoteImageFilename: social-proof-logo-osquery-140x36@2x.png - quoteLinkUrl: https://twitter.com/osquery + quoteLinkUrl: https://www.linkedin.com/in/marpaia/ quoteAuthorName: Mike Arpaia - quoteAuthorJobTitle: Creator of - quoteAuthorSocialHandle: "@osquery" + quoteAuthorProfileImageFilename: testimonial-author-mike-arpaia-48x48@2x.png + quoteAuthorJobTitle: Creator of osquery + productCategories: [Endpoint operations, Vulnerability management] - quote: "#osquery is one of the best tools out there and #fleetdm 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. I have used it on 15k servers and it’s really scalable." - quoteImageFilename: social-proof-logo-wayfair-136x32@2x.png - quoteLinkUrl: https://twitter.com/Wayfair + quoteImageFilename: logo-salesforce-57x40@2x.png + quoteLinkUrl: https://www.linkedin.com/in/anelshaer/ quoteAuthorName: Ahmed Elshaer + quoteAuthorProfileImageFilename: testimonial-author-ahmed-elshaer-48x48@2x.png quoteAuthorJobTitle: DFIR, Blue Teaming, SecOps - quoteAuthorSocialHandle: "@wayfair" + productCategories: [Endpoint operations] - quote: 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. quoteImageFilename: social-proof-logo-comcast-107x38@2x.png - quoteLinkUrl: https://twitter.com/comcast + quoteLinkUrl: https://www.linkedin.com/in/abubakar-yousafzai-b7213659/ quoteAuthorName: Abubakar Yousafzai + quoteAuthorProfileImageFilename: testimonial-author-abubakar-yousafzai-48x48@2x.png quoteAuthorJobTitle: Security Software Development & Engineering - quoteAuthorSocialHandle: "@Comcast" + productCategories: [Endpoint operations] - quote: One of the best teams out there to go work for and help shape security platforms. quoteImageFilename: logo-deloitte-166x36@2x.png - quoteLinkUrl: https://www.linkedin.com/company/deloitte/ + quoteLinkUrl: https://www.linkedin.com/in/neondhruv/ quoteAuthorName: Dhruv Majumdar + quoteAuthorProfileImageFilename: testimonial-author-dhruv-majumdar-48x48@2x.png quoteAuthorJobTitle: Director Of Cyber Risk & Advisory - quoteAuthorSocialHandle: "@Deloitte" - - - + productCategories: [Vulnerability management, Endpoint operations] +- + quote: When we look at vendors, we look for ones that are very receptive to feedback, where you’re just part of the family, I guess. Fleet’s really good at that. + quoteAuthorName: Harrison Ravazzolo + quoteAuthorProfileImageFilename: testimonial-author-harrison-ravazzolo-48x48@2x.png + quoteLinkUrl: https://www.linkedin.com/in/harrison-ravazzolo/ + quoteAuthorJobTitle: Lead platform and identity engineer + productCategories: [Endpoint operations] +- + quote: Fleet has such a huge amount of use cases. My goal was to get telemetry on endpoints, but then our IR team, our TBM team, and multiple other folks in security started heavily utilizing the system in ways I didn’t expect. It spread so naturally, even our corporate and infrastructure teams want to run it. + quoteAuthorName: Charles Zaffery + quoteLinkUrl: https://www.linkedin.com/in/charleszaffery/ + quoteAuthorJobTitle: Principle computer janitor + quoteAuthorProfileImageFilename: testimonial-author-charles-zaffery-48x48@2x.png + productCategories: [Endpoint operations] +- + quote: I don't want one bad actor to brick my fleet, I want them to make a pull request first. + quoteAuthorName: Matt Carr + quoteAuthorJobTitle: CPE manager + quoteAuthorProfileImageFilename: testimonial-author-matt-carr-48x48@2x.png + quoteLinkUrl: https://www.linkedin.com/in/mathewcarr/ + productCategories: [Device management] +- + quote: I wanted an easy way to control osquery configurations, and I wanted to stream data as fast as possible into Snowflake. No other solution jumped out to solve those things except for Fleet. + quoteAuthorName: Tom Larkin + quoteAuthorJobTitle: IT Engineering Manager + quoteAuthorProfileImageFilename: testimonial-author-tom-larkin-48x48@2x.png + quoteLinkUrl: https://www.linkedin.com/in/thlarkin/ + productCategories: [Endpoint operations] \ No newline at end of file diff --git a/website/api/controllers/view-endpoint-ops.js b/website/api/controllers/view-endpoint-ops.js index 55f44b13c8..8427fe103d 100644 --- a/website/api/controllers/view-endpoint-ops.js +++ b/website/api/controllers/view-endpoint-ops.js @@ -21,7 +21,24 @@ module.exports = { throw {badConfig: 'builtStaticContent.testimonials'}; } // Get testimonials for the component. - let testimonialsForScrollableTweets = sails.config.builtStaticContent.testimonials; + let testimonialsForScrollableTweets = _.clone(sails.config.builtStaticContent.testimonials); + + // Filter the testimonials by product category + testimonialsForScrollableTweets = _.filter(testimonialsForScrollableTweets, (testimonial)=>{ + return _.contains(testimonial.productCategories, 'Endpoint operations'); + }); + + // Specify an order for the testimonials on this page using the last names of quote authors + let testimonialOrderForThisPage = ['Anderson','Grzelak','Fohs','Shaklovitz','Waisman','Arpaia','Gomez','Shields','Majumdar','Elshaer','Yousafzai','Botelho','Zaffery','Larkin','Ravazzolo','Whetstone']; + testimonialsForScrollableTweets.sort((a, b)=>{ + if(testimonialOrderForThisPage.indexOf(a.quoteAuthorName.split(' ')[1]) === -1){ + return 1; + } else if(testimonialOrderForThisPage.indexOf(b.quoteAuthorName.split(' ')[1]) === -1) { + return -1; + } + return testimonialOrderForThisPage.indexOf(a.quoteAuthorName.split(' ')[1]) - testimonialOrderForThisPage.indexOf(b.quoteAuthorName.split(' ')[1]); + }); + // Respond with view. return { testimonialsForScrollableTweets, diff --git a/website/api/controllers/view-fleet-mdm.js b/website/api/controllers/view-fleet-mdm.js index 94aa452951..95341354a9 100644 --- a/website/api/controllers/view-fleet-mdm.js +++ b/website/api/controllers/view-fleet-mdm.js @@ -21,7 +21,24 @@ module.exports = { throw {badConfig: 'builtStaticContent.testimonials'}; } // Get testimonials for the component. - let testimonialsForScrollableTweets = sails.config.builtStaticContent.testimonials; + let testimonialsForScrollableTweets = _.clone(sails.config.builtStaticContent.testimonials); + + // Filter the testimonials by product category + testimonialsForScrollableTweets = _.filter(testimonialsForScrollableTweets, (testimonial)=>{ + return _.contains(testimonial.productCategories, 'Device management'); + }); + + // Specify an order for the testimonials on this page using the last names of quote authors + let testimonialOrderForThisPage = ['Gomez', 'Fohs', 'Grzelak', 'Botelho', 'Whetstone', 'Carr']; + testimonialsForScrollableTweets.sort((a, b)=>{ + if(testimonialOrderForThisPage.indexOf(a.quoteAuthorName.split(' ')[1]) === -1){ + return 1; + } else if(testimonialOrderForThisPage.indexOf(b.quoteAuthorName.split(' ')[1]) === -1) { + return -1; + } + return testimonialOrderForThisPage.indexOf(a.quoteAuthorName.split(' ')[1]) - testimonialOrderForThisPage.indexOf(b.quoteAuthorName.split(' ')[1]); + }); + // Respond with view. return { testimonialsForScrollableTweets, diff --git a/website/api/controllers/view-vulnerability-management.js b/website/api/controllers/view-vulnerability-management.js index cc4f2af9ff..ba94cbb8a4 100644 --- a/website/api/controllers/view-vulnerability-management.js +++ b/website/api/controllers/view-vulnerability-management.js @@ -21,7 +21,25 @@ module.exports = { throw {badConfig: 'builtStaticContent.testimonials'}; } // Get testimonials for the component. - let testimonialsForScrollableTweets = sails.config.builtStaticContent.testimonials; + let testimonialsForScrollableTweets = _.clone(sails.config.builtStaticContent.testimonials); + + // Filter the testimonials by product category + testimonialsForScrollableTweets = _.filter(testimonialsForScrollableTweets, (testimonial)=>{ + return _.contains(testimonial.productCategories, 'Vulnerability management'); + }); + + // Specify an order for the testimonials on this page using the last names of quote authors + let testimonialOrderForThisPage = ['Waisman', 'Shields', 'Majumdar', 'Anderson', 'Grzelak', 'Fohs', 'Arpaia', 'Gomez', 'Whetstone']; + testimonialsForScrollableTweets.sort((a, b)=>{ + if(testimonialOrderForThisPage.indexOf(a.quoteAuthorName.split(' ')[1]) === -1){ + return 1; + } else if(testimonialOrderForThisPage.indexOf(b.quoteAuthorName.split(' ')[1]) === -1) { + return -1; + } + return testimonialOrderForThisPage.indexOf(a.quoteAuthorName.split(' ')[1]) - testimonialOrderForThisPage.indexOf(b.quoteAuthorName.split(' ')[1]); + }); + + console.log(testimonialsForScrollableTweets.length); // Respond with view. return { testimonialsForScrollableTweets, diff --git a/website/assets/images/logo-lyft-46x32@2x.png b/website/assets/images/logo-lyft-46x32@2x.png new file mode 100644 index 0000000000..a46e949402 Binary files /dev/null and b/website/assets/images/logo-lyft-46x32@2x.png differ diff --git a/website/assets/images/logo-salesforce-57x40@2x.png b/website/assets/images/logo-salesforce-57x40@2x.png new file mode 100644 index 0000000000..059c833c83 Binary files /dev/null and b/website/assets/images/logo-salesforce-57x40@2x.png differ diff --git a/website/assets/images/logo-stripe-57x24@2x.png b/website/assets/images/logo-stripe-57x24@2x.png new file mode 100644 index 0000000000..6263eb139c Binary files /dev/null and b/website/assets/images/logo-stripe-57x24@2x.png differ diff --git a/website/assets/images/testimonial-author-abubakar-yousafzai-48x48@2x.png b/website/assets/images/testimonial-author-abubakar-yousafzai-48x48@2x.png new file mode 100644 index 0000000000..d91b7c4e2c Binary files /dev/null and b/website/assets/images/testimonial-author-abubakar-yousafzai-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-ahmed-elshaer-48x48@2x.png b/website/assets/images/testimonial-author-ahmed-elshaer-48x48@2x.png new file mode 100644 index 0000000000..abf0aeeb71 Binary files /dev/null and b/website/assets/images/testimonial-author-ahmed-elshaer-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-andre-shields-48x48@2x.png b/website/assets/images/testimonial-author-andre-shields-48x48@2x.png new file mode 100644 index 0000000000..5f0e582ebc Binary files /dev/null and b/website/assets/images/testimonial-author-andre-shields-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-austin-anderson-48x48@2x.png b/website/assets/images/testimonial-author-austin-anderson-48x48@2x.png new file mode 100644 index 0000000000..f182323d27 Binary files /dev/null and b/website/assets/images/testimonial-author-austin-anderson-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-brendan-shaklovitz-48x48@2x.png b/website/assets/images/testimonial-author-brendan-shaklovitz-48x48@2x.png new file mode 100644 index 0000000000..6c4aade881 Binary files /dev/null and b/website/assets/images/testimonial-author-brendan-shaklovitz-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-charles-zaffery-48x48@2x.png b/website/assets/images/testimonial-author-charles-zaffery-48x48@2x.png new file mode 100644 index 0000000000..b68c9c1b3b Binary files /dev/null and b/website/assets/images/testimonial-author-charles-zaffery-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-daniel-grzelak-48x48@2x.png b/website/assets/images/testimonial-author-daniel-grzelak-48x48@2x.png new file mode 100644 index 0000000000..f3f4410411 Binary files /dev/null and b/website/assets/images/testimonial-author-daniel-grzelak-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-dhruv-majumdar-48x48@2x.png b/website/assets/images/testimonial-author-dhruv-majumdar-48x48@2x.png new file mode 100644 index 0000000000..1a66170438 Binary files /dev/null and b/website/assets/images/testimonial-author-dhruv-majumdar-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-erik-gomez-48x48@2x.png b/website/assets/images/testimonial-author-erik-gomez-48x48@2x.png new file mode 100644 index 0000000000..5d263e1517 Binary files /dev/null and b/website/assets/images/testimonial-author-erik-gomez-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-harrison-ravazzolo-48x48@2x.png b/website/assets/images/testimonial-author-harrison-ravazzolo-48x48@2x.png new file mode 100644 index 0000000000..d3cf693660 Binary files /dev/null and b/website/assets/images/testimonial-author-harrison-ravazzolo-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-kenny-botelho-48x48@2x.png b/website/assets/images/testimonial-author-kenny-botelho-48x48@2x.png new file mode 100644 index 0000000000..8af46d15a5 Binary files /dev/null and b/website/assets/images/testimonial-author-kenny-botelho-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-matt-carr-48x48@2x.png b/website/assets/images/testimonial-author-matt-carr-48x48@2x.png new file mode 100644 index 0000000000..bbc6fb529d Binary files /dev/null and b/website/assets/images/testimonial-author-matt-carr-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-mike-arpaia-48x48@2x.png b/website/assets/images/testimonial-author-mike-arpaia-48x48@2x.png new file mode 100644 index 0000000000..55321e0c60 Binary files /dev/null and b/website/assets/images/testimonial-author-mike-arpaia-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-nick-fohs-24x24@2x.png b/website/assets/images/testimonial-author-nick-fohs-24x24@2x.png new file mode 100644 index 0000000000..244cfae6f4 Binary files /dev/null and b/website/assets/images/testimonial-author-nick-fohs-24x24@2x.png differ diff --git a/website/assets/images/testimonial-author-nico-waisman-48x48@2x.png b/website/assets/images/testimonial-author-nico-waisman-48x48@2x.png new file mode 100644 index 0000000000..02aa9fcb08 Binary files /dev/null and b/website/assets/images/testimonial-author-nico-waisman-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-tom-larkin-48x48@2x.png b/website/assets/images/testimonial-author-tom-larkin-48x48@2x.png new file mode 100644 index 0000000000..97f6dbf60a Binary files /dev/null and b/website/assets/images/testimonial-author-tom-larkin-48x48@2x.png differ diff --git a/website/assets/images/testimonial-author-wes-whetstone-48x48@2x.png b/website/assets/images/testimonial-author-wes-whetstone-48x48@2x.png new file mode 100644 index 0000000000..d507b58a73 Binary files /dev/null and b/website/assets/images/testimonial-author-wes-whetstone-48x48@2x.png differ diff --git a/website/assets/js/components/scrollable-tweets.component.js b/website/assets/js/components/scrollable-tweets.component.js index 42f73eae81..26c2258dca 100644 --- a/website/assets/js/components/scrollable-tweets.component.js +++ b/website/assets/js/components/scrollable-tweets.component.js @@ -42,31 +42,30 @@ parasails.registerComponent('scrollableTweets', { template: `
-
-
- + +
+
-

+

{{testimonial.quote}} - See the video. + See the video.

-
-
-

{{testimonial.quoteAuthorName}}

-

- {{testimonial.quoteAuthorJobTitle}} - {{testimonial.quoteAuthorSocialHandle}} - -

+
+
+ +
+
+

{{testimonial.quoteAuthorName}}

+

{{testimonial.quoteAuthorJobTitle}}

-
+
- +
diff --git a/website/assets/styles/components/scrollable-tweets.component.less b/website/assets/styles/components/scrollable-tweets.component.less index 2fe2e3e68f..3104775e8d 100644 --- a/website/assets/styles/components/scrollable-tweets.component.less +++ b/website/assets/styles/components/scrollable-tweets.component.less @@ -25,17 +25,41 @@ -ms-overflow-style: none; } - [purpose='video-link'] { - cursor: pointer; - color: @core-vibrant-blue; - } [purpose='tweet-card'] { - img { - max-height: 38px; + [purpose='logo'] { + img { + max-height: 40px; + } + min-height: 24px; + margin-bottom: 24px; } - max-width: 367px; - min-width: 367px; + [purpose='quote'] { + margin-bottom: 24px; + } + [purpose='quote-author-info'] { + [purpose='job-title'] { + font-size: 12px !important;//lesshint-disable-line importantRule,duplicateProperty + line-height: 18px !important;//lesshint-disable-line importantRule,duplicateProperty + } + [purpose='name'] { + color: @core-fleet-black !important;//lesshint-disable-line importantRule,duplicateProperty + } + [purpose='profile-picture'] { + margin-right: 16px; + img { + height: 48px; + width: 48px; + } + } + } + [purpose='video-link'] { + cursor: pointer; + color: @core-vibrant-blue; + } + height: fit-content; + max-width: 360px; + min-width: 360px; display: flex; flex-direction: column; justify-content: center; @@ -47,8 +71,12 @@ padding: 40px; border: 1px solid @core-vibrant-blue-15; box-sizing: border-box; - box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.1); border-radius: 16px; + &:hover { + text-decoration: none; + pointer: cursor; + box-shadow: 0px 4px 16px rgba(0, 0, 0, 0.1); + } } [purpose='page-indictator-container'] { diff --git a/website/scripts/build-static-content.js b/website/scripts/build-static-content.js index 463bd52570..cafcb79b82 100644 --- a/website/scripts/build-static-content.js +++ b/website/scripts/build-static-content.js @@ -865,13 +865,13 @@ module.exports = { async()=>{ // Validate the pricing table yaml and add it to builtStaticContent.pricingTable. let RELATIVE_PATH_TO_TESTIMONIALS_YML_IN_FLEET_REPO = 'handbook/company/testimonials.yml'; - // let url = require('url'); + let VALID_PRODUCT_CATEGORIES = ['Endpoint operations', 'Device management', 'Vulnerability management']; let yaml = await sails.helpers.fs.read(path.join(topLvlRepoPath, RELATIVE_PATH_TO_TESTIMONIALS_YML_IN_FLEET_REPO)).intercept('doesNotExist', (err)=>new Error(`Could not find testimonials YAML file at "${RELATIVE_PATH_TO_TESTIMONIALS_YML_IN_FLEET_REPO}". Was it accidentally moved? Raw error: `+err.message)); let testimonials = YAML.parse(yaml, {prettyErrors: true}); for(let testimonial of testimonials){ // Throw an error if any value in the testimonial yaml is not a string. - for(let key of _.keys(testimonial)){ - if(typeof testimonial[key] !== 'string'){ + for(let key of _.keys(testimonial)) { + if(typeof testimonial[key] !== 'string' && key !== 'productCategories'){ throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial contains a ${key} with a non-string value. Please make sure all values in testimonials.yml are strings, and try running this script again. Invalid (${typeof testimonial[key]}) ${key} value: ${testimonial[key]}`); } } @@ -882,10 +882,28 @@ module.exports = { if(!testimonial.quoteAuthorName) { throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial is missing a "quoteAuthorName". To resolve, make sure all testimonials have a "quoteAuthorName", and try running this script again. Testimonial with missing "quoteAuthorName": ${testimonial} `); } - // If quoteAuthorSocialHandle is provided, quoteLinkUrl is required. - if(testimonial.quoteAuthorSocialHandle) { - if(!testimonial.quoteLinkUrl){ - throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial with a "quoteAuthorSocialHandle" value is missing a "quoteLinkUrl". To resolve, make sure all testimonials with a "quoteAuthorSocialHandle" have a "quoteLinkUrl", and try running this script again. Testimonial with missing "quoteLinkUrl": ${testimonial} `); + if(!testimonial.quoteLinkUrl){ + throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial is missing a "quoteLinkUrl" (A link to the quote author's LinkedIn profile). To resolve, make sure all testimonials have a "quoteLinkUrl", and try running this script again. Testimonial with missing "quoteLinkUrl": ${testimonial} `); + } + if(!testimonial.quoteAuthorProfileImageFilename){ + throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial is missing a "quoteAuthorProfileImageFilename" (The quote author's LinkedIn profile picture). To resolve, make sure all testimonials have a "quoteAuthorProfileImageFilename", and try running this script again. Testimonial with missing "quoteAuthorProfileImageFilename": ${testimonial} `); + } else { + let imageFileExists = await sails.helpers.fs.exists(path.join(topLvlRepoPath, 'website/assets/images/', testimonial.quoteAuthorProfileImageFilename)); + if(!imageFileExists){ + throw new Error(`Could not build testimonials config from testimonials.yml. A testimonial has a 'quoteAuthorProfileImageFilename' value that points to an image that doesn't exist. Please make sure the file exists in the /website/assets/images/ folder. Invalid quoteImageFilename value: ${testimonial.quoteImageFilename}`); + } + } + if(!testimonial.productCategories) { + throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial is missing a 'productCategories' value. Please add an array of product categories to this testimonial and try running this script again`); + } else { + if(!_.isArray(testimonial.productCategories)){ + throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial has a has an invalid 'productCategories' value. Please change the productCategories for this testimonial to be an array of product categories`); + } else { + for(let category of testimonial.productCategories){ + if(!_.contains(VALID_PRODUCT_CATEGORIES, category)){ + throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial has a 'productCategories' with an an invalid product category (${category}). Please change the values in this array to be one of: ${VALID_PRODUCT_CATEGORIES.join(', ')}`); + } + } } } // If the testimonial has a youtubeVideoUrl, we'll validate the link and add the video ID so we can embed the video in a modal. @@ -919,13 +937,13 @@ module.exports = { throw new Error(`Could not build testimonial config from testimonials.yml. A testimonial with a 'quoteImageFilename' value is missing a 'quoteLinkUrl'. If providing a 'quoteImageFilename', a quoteLinkUrl (The link that the image will go to) is required. Testimonial missing a quoteLinkUrl: ${testimonial}`); } // Check if the image used for the testimonials exists. - let imageFileExists = await sails.helpers.fs.exists(path.join(topLvlRepoPath, 'website/assets/images/'+testimonial.quoteImageFilename)); + let imageFileExists = await sails.helpers.fs.exists(path.join(topLvlRepoPath, 'website/assets/images/', testimonial.quoteImageFilename)); if(!imageFileExists){ throw new Error(`Could not build testimonials config from testimonials.yml. A testimonial has a 'quoteImageFilename' value that points to an image that doesn't exist. Please make sure the file exists in the /website/assets/images/ folder. Invalid quoteImageFilename value: ${testimonial.quoteImageFilename}`); } let imageFilenameMatchesWebsiteConventions = testimonial.quoteImageFilename.match(/\d+x\d+@2x\.png|jpg|jpeg$/g); - if(!imageFilenameMatchesWebsiteConventions){ - throw new Error('image naming conventions (but secretly, we\'ll be relying on this to set the images height in frontend land)'); + if(!imageFilenameMatchesWebsiteConventions) { + throw new Error(`Could not build testimonials config from testimonials.yml. A testimonial has a quoteImageFilename that does not match the website\'s naming conventions. To resolve, make sure that the images dimensions are added to the filename, and that the filename ends with @2x. Filename that does not match the Fleet website's naming conventions: ${testimonial.quoteImageFilename}`); } // Strip the 2x from the filename, using image dimensions we matched when we checked if the filename matches website conventions. let extensionlessFilenameWithPostfixRemoved = imageFilenameMatchesWebsiteConventions[0].split('@2x')[0];