From be14f7c10de6ebca460e6b9f1aafe324bc47b2dc Mon Sep 17 00:00:00 2001 From: Eric Date: Thu, 16 Apr 2026 09:14:28 -0500 Subject: [PATCH] Website: Add webinar article template page. (#43627) Changes: - Added support for a new article category: `webinar`. - Added a template page for webinar articles. - Added an additional route for webinar articles that users are taken to to watch the webinar recording. - Added `deliver-webinar-access-request`, an action that updates CRM records when users fill out the form on the webinar template page. - Updated the accepted `intentSignal` values in the create-historical-event helper. - Added an article for the "Beyond the hype, practical AI for device management" webinar. ## Summary by CodeRabbit * **New Features** * Public webinar pages (/webinars/:slug and /watch) with optional embedded video and a new page template, script, and styles. * Sidebar signup form (first name, last name, work email) with prefill for signed-in users and improved scroll behavior. * POST API to request webinar access: validates email domain, records a webinar-request event, triggers background CRM sync, and returns a watch view on success. * Static-site build now recognizes webinar articles and enforces embedded-video URL validation. --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- ...hype-practical-AI-for-device-management.md | 26 + handbook/company/writing.md | 7 + .../articles/view-basic-webinar.js | 66 ++ .../deliver-webinar-access-request.js | 77 ++ .../salesforce/create-historical-event.js | 1 + website/assets/js/cloud.setup.js | 2 +- .../js/pages/articles/basic-webinar.page.js | 76 ++ website/assets/styles/importer.less | 1 + .../styles/pages/articles/basic-webinar.less | 749 ++++++++++++++++++ website/config/policies.js | 1 + website/config/routes.js | 18 + website/scripts/build-static-content.js | 20 +- website/views/layouts/layout.ejs | 1 + .../views/pages/articles/basic-webinar.ejs | 97 +++ 14 files changed, 1139 insertions(+), 3 deletions(-) create mode 100644 articles/beyond-the-hype-practical-AI-for-device-management.md create mode 100644 website/api/controllers/articles/view-basic-webinar.js create mode 100644 website/api/controllers/deliver-webinar-access-request.js create mode 100644 website/assets/js/pages/articles/basic-webinar.page.js create mode 100644 website/assets/styles/pages/articles/basic-webinar.less create mode 100644 website/views/pages/articles/basic-webinar.ejs diff --git a/articles/beyond-the-hype-practical-AI-for-device-management.md b/articles/beyond-the-hype-practical-AI-for-device-management.md new file mode 100644 index 0000000000..970c41dcd9 --- /dev/null +++ b/articles/beyond-the-hype-practical-AI-for-device-management.md @@ -0,0 +1,26 @@ +## Moving from manual engineering workflows to AI + +AI promises to transform IT—but what does that actually look like for teams managing devices at scale? This session brings together practitioners from Fleet and Foursquare to share hard-won lessons from modernizing their device management practices: consolidating tools for radical visibility across platforms, adopting GitOps to bring stability and accountability to fleet operations, and using AI to accelerate engineering output without adding headcount. + +If you're leading an IT or corporate engineering team and wondering how to move from fragmented, manual device management toward a more programmable, resilient, efficient, and auditable approach—this is the session for you. + +### What you will learn + +- Why consolidating onto a single, cross-platform device management solution changes how your team sees and operates its entire environment. +- How GitOps reduces risk and improves change management—and why it's a prerequisite for using AI safely. +- How AI tools empower your team to do more—without replacing the judgment and expertise they bring. +- How these practices give smaller teams the ability to scale and operate like larger ones. + +As device management complexity grows, IT and platform teams are rethinking how they work, not just what tools they use. Join Allen Houchins (Fleet), Harley Williams (Senior Systems Engineer), and Mike Meyer (Senior Manager of Corporate Engineering) from Foursquare for a practical look at how consolidating tooling, adopting GitOps, and integrating AI have changed the way their teams operate. You'll walk away with real-world lessons on what worked, what didn't, and how these shifts are reshaping the future of device management engineering. + + + + + + + + + + + + diff --git a/handbook/company/writing.md b/handbook/company/writing.md index c2b78d8496..237ad3db4f 100644 --- a/handbook/company/writing.md +++ b/handbook/company/writing.md @@ -59,6 +59,7 @@ We use `` tags in Markdown articles to set metadata information about the - `comparison` - Articles that present a comparison between Fleet and a competing product. Articles in this category are only visible in the list of all articles at [fleetdm.com/blog](/blog) - `articles` - A catch-all category for articles and blog posts that do not fit into other categories. Articles in this category are only visible in the list of all articles at [fleetdm.com/blog](/blog) - `whitepaper` - Articles that offer a downloadable PDF that is gated behind the user filling out a form. Articles in this category are available at [fleetdm.com/whitepapers](/whitepapers) + - `webinar` - Articles that offer a recording of a webinar hosted by Fleet that is gated behind the user filling out a form. - `publishedOn`: An ISO 8601 formatted date (YYYY-MM-DD) of the articles publish date. If the article is a guide, this value should be updated whenever a change to the guide is made. - Optional meta tags: - `articleImageUrl`: A relative link to a cover image for the article used for social share previews. If provided, the image needs to live in the /website/assets/images/articles folder. @@ -179,6 +180,12 @@ Whitepaper articles use a separate article template that requires additional `{ + let recordIds = await sails.helpers.salesforce.updateOrCreateContactAndAccount.with({ + emailAddress: emailAddress, + firstName: firstName, + lastName: lastName, + contactSource: 'Website - Contact forms', + description: `Submitted a form to watch the ${webinarName} webinar.`, + marketingAttributionCookie: attributionCookieOrUndefined + }).intercept((err)=>{ + return new Error(`Could not create/update a contact or account. Full error: ${require('util').inspect(err)}`); + }); + + // If the Contact record returned by the updateOrCreateContactAndAccount does not have a parent Account record, throw an error to stop the build helper. + if(!recordIds.salesforceAccountId) { + throw new Error(`Could not create historical event. The contact record (ID: ${recordIds.salesforceContactId}) returned by the updateOrCreateContactAndAccount helper is missing a parent account record.`); + } + // Create the new Fleet website page view record. + await sails.helpers.salesforce.createHistoricalEvent.with({ + salesforceAccountId: recordIds.salesforceAccountId, + salesforceContactId: recordIds.salesforceContactId, + eventType: 'Intent signal', + intentSignal: 'Requested webinar recording', + eventContent: webinarName, + }).intercept((err)=>{ + return new Error(`Could not create an historical event. Full error: ${require('util').inspect(err)}`); + }); + }).exec((err)=>{ + if(err){ + sails.log.warn(`Background task failed: When a user (email: ${emailAddress} submitted a form to watch the ${webinarName} webinar, a Contact/Account/website activity record could not be created/updated in the CRM.`, require('util').inspect(err)); + } + return; + });//_∏_ + + // All done. + return; + + } + + +}; diff --git a/website/api/helpers/salesforce/create-historical-event.js b/website/api/helpers/salesforce/create-historical-event.js index 1d53c99064..c0d0a6bc43 100644 --- a/website/api/helpers/salesforce/create-historical-event.js +++ b/website/api/helpers/salesforce/create-historical-event.js @@ -66,6 +66,7 @@ module.exports = { 'Signed up for a fleetdm.com account', 'Requested whitepaper download', 'Created a quote for a self-service Fleet Premium license', + 'Requested webinar recording', ] }, eventContent: { diff --git a/website/assets/js/cloud.setup.js b/website/assets/js/cloud.setup.js index de5280db7b..cff8dec382 100644 --- a/website/assets/js/cloud.setup.js +++ b/website/assets/js/cloud.setup.js @@ -13,7 +13,7 @@ Cloud.setup({ /* eslint-disable */ - methods: {"redirectToStripeBillingPortal":{"verb":"GET","url":"/customers/update-subscription","args":[]},"downloadSitemap":{"verb":"GET","url":"/sitemap.xml","args":[]},"downloadRssFeed":{"verb":"GET","url":"/rss/:categoryName","args":["categoryName"]},"receiveUsageAnalytics":{"verb":"POST","url":"/api/v1/webhooks/receive-usage-analytics","args":["anonymousIdentifier","fleetVersion","licenseTier","numHostsEnrolled","numUsers","numTeams","numPolicies","numLabels","softwareInventoryEnabled","vulnDetectionEnabled","systemUsersEnabled","hostsStatusWebHookEnabled","numWeeklyActiveUsers","numWeeklyPolicyViolationDaysActual","numWeeklyPolicyViolationDaysPossible","hostsEnrolledByOperatingSystem","hostsEnrolledByOrbitVersion","hostsEnrolledByOsqueryVersion","storedErrors","numHostsNotResponding","organization","mdmMacOsEnabled","mdmWindowsEnabled","liveQueryDisabled","hostExpiryEnabled","numSoftwareVersions","numHostSoftwares","numSoftwareTitles","numHostSoftwareInstalledPaths","numSoftwareCPEs","numSoftwareCVEs","aiFeaturesDisabled","maintenanceWindowsEnabled","maintenanceWindowsConfigured","numHostsFleetDesktopEnabled","numQueries","numHostsABMPending","fleetMaintainedAppsWindows","fleetMaintainedAppsMacOS"]},"receiveFromGithub":{"verb":"GET","url":"/api/v1/webhooks/github","args":["botSignature","action","sender","repository","changes","issue","comment","pull_request","label","release","projects_v2_item"]},"receiveFromStripe":{"verb":"POST","url":"/api/v1/webhooks/receive-from-stripe","args":["id","type","data","webhookSecret"]},"receiveFromZapier":{"verb":"POST","url":"/api/v1/webhooks/receive-from-zapier","args":["eventName","data","webhookSecret"]},"receiveFromClay":{"verb":"POST","url":"/api/v1/webhooks/receive-from-clay","args":["webhookSecret","firstName","lastName","linkedinUrl","emailAddress","contactSource","jobTitle","intentSignal","historicalContent","historicalContentUrl","relatedCampaign"]},"getEstDeviceCertificate":{"verb":"POST","url":"/api/v1/get-est-device-certificate","args":["csrData","authToken","introspectEndpoint","idpClientId","estEndpoint","estClientId","estClientKey"]},"createAndroidSignupUrl":{"verb":"POST","url":"/api/android/v1/signupUrls","args":["callbackUrl"]},"createAndroidEnterprise":{"verb":"POST","url":"/api/android/v1/enterprises","args":["signupUrlName","enterpriseToken","fleetLicenseKey","pubsubPushUrl","enterprise"]},"getAndroidEnterprises":{"verb":"GET","url":"/api/android/v1/enterprises","args":[]},"createAndroidEnrollmentToken":{"verb":"POST","url":"/api/android/v1/enterprises/:androidEnterpriseId/enrollmentTokens","args":["androidEnterpriseId"]},"modifyAndroidPolicies":{"verb":"PATCH","url":"/api/android/v1/enterprises/:androidEnterpriseId/policies/:policyId","args":["androidEnterpriseId","policyId"]},"deleteOneAndroidEnterprise":{"verb":"DELETE","url":"/api/android/v1/enterprises/:androidEnterpriseId","args":["androidEnterpriseId"]},"getAndroidDevice":{"verb":"GET","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices/:deviceId","args":["androidEnterpriseId","deviceId"]},"getAndroidDevices":{"verb":"GET","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices","args":["androidEnterpriseId","pageSize","pageToken","fields"]},"deleteAndroidDevice":{"verb":"DELETE","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices/:deviceId","args":["androidEnterpriseId","deviceId"]},"modifyAndroidDevice":{"verb":"PATCH","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices/:deviceId","args":["androidEnterpriseId","deviceId"]},"getEnterpriseApplications":{"verb":"GET","url":"/api/android/v1/enterprises/:androidEnterpriseId/applications/:applicationId","args":["androidEnterpriseId","applicationId"]},"modifyEnterpriseAppPolicy":{"verb":"POST","url":"/api/android/v1/enterprises/:androidEnterpriseId/policies/:policyId::googleAction","args":["androidEnterpriseId","policyId","googleAction","packageNames","changes"]},"createEnterpriseWebapp":{"verb":"POST","url":"/api/android/v1/enterprises/:androidEnterpriseId/webApps","args":["androidEnterpriseId","title","startUrl","icons","displayMode","versionCode"]},"deliverContactFormMessage":{"verb":"POST","url":"/api/v1/deliver-contact-form-message","args":["emailAddress","firstName","lastName","message"]},"sendPasswordRecoveryEmail":{"verb":"POST","url":"/api/v1/entrance/send-password-recovery-email","args":["emailAddress"]},"signup":{"verb":"POST","url":"/api/v1/customers/signup","args":["emailAddress","password","organization","firstName","lastName","signupReason"]},"updateProfile":{"verb":"POST","url":"/api/v1/account/update-profile","args":["firstName","lastName","organization","emailAddress"]},"updatePassword":{"verb":"POST","url":"/api/v1/account/update-password","args":["oldPassword","newPassword"]},"updateBillingCard":{"verb":"POST","url":"/api/v1/account/update-billing-card","args":["stripeToken","billingCardLast4","billingCardBrand","billingCardExpMonth","billingCardExpYear"]},"login":{"verb":"POST","url":"/api/v1/customers/login","args":["emailAddress","password","rememberMe"]},"logout":{"verb":"GET","url":"/api/v1/account/logout","args":[]},"createQuote":{"verb":"POST","url":"/api/v1/customers/create-quote","args":["macosHosts","windowsHosts","linuxHosts","iosHosts","androidHosts","otherHosts"]},"saveBillingInfoAndSubscribe":{"verb":"POST","url":"/api/v1/customers/save-billing-info-and-subscribe","args":["quoteId","organization","firstName","lastName","paymentSource"]},"updatePasswordAndLogin":{"verb":"POST","url":"/api/v1/entrance/update-password-and-login","args":["password","token"]},"deliverDemoSignup":{"verb":"POST","url":"/api/v1/deliver-demo-signup","args":["emailAddress"]},"createOrUpdateOneNewsletterSubscription":{"verb":"POST","url":"/api/v1/create-or-update-one-newsletter-subscription","args":["emailAddress"]},"unsubscribeFromAllNewsletters":{"verb":"GET","url":"/api/v1/unsubscribe-from-all-newsletters","args":["emailAddress"]},"buildLicenseKey":{"verb":"POST","url":"/api/v1/admin/build-license-key","args":["numberOfHosts","organization","expiresAt","partnerName"]},"createVantaAuthorizationRequest":{"verb":"POST","url":"/api/v1/create-vanta-authorization-request","args":["emailAddress","fleetInstanceUrl","fleetApiKey","redirectToExternalPageAfterAuthorization","sharedSecret"]},"redirectVantaAuthorizationRequest":{"verb":"GET","url":"/redirect-vanta-authorization-request","args":["vantaSourceId","state","vantaAuthorizationRequestURL","redirectAfterSetup"]},"deliverMdmBetaSignup":{"verb":"POST","url":"/api/v1/deliver-mdm-beta-signup","args":["emailAddress","fullName","jobTitle","numberOfHosts"]},"getHumanInterpretationFromOsquerySql":{"verb":"POST","url":"/api/v1/get-human-interpretation-from-osquery-sql","args":["sql"]},"deliverAppleCsr":{"verb":"POST","url":"/api/v1/deliver-apple-csr","args":["unsignedCsrData","deliveryMethod"]},"deliverMdmDemoEmail":{"verb":"POST","url":"/api/v1/deliver-mdm-demo-email","args":["emailAddress"]},"provisionSandboxInstanceAndDeliverEmail":{"verb":"POST","url":"/api/v1/admin/provision-sandbox-instance-and-deliver-email","args":["userId"]},"deliverTalkToUsFormSubmission":{"verb":"POST","url":"/api/v1/deliver-talk-to-us-form-submission","args":["emailAddress","firstName","lastName","organization","numberOfHosts","primaryBuyingSituation"]},"saveQuestionnaireProgress":{"verb":"POST","url":"/api/v1/save-questionnaire-progress","args":["currentStep","formData"]},"updateStartCtaVisibility":{"verb":"POST","url":"/api/v1/account/update-start-cta-visibility","args":[]},"deliverDealRegistrationSubmission":{"verb":"POST","url":"/api/v1/deliver-deal-registration-submission","args":["submittersFirstName","submittersLastName","submittersEmailAddress","submittersOrganization","customersFirstName","customersLastName","customersEmailAddress","linkedinUrl","customersOrganization","customersCurrentMdm","otherMdmEvaluated","preferredHosting","expectedDealSize","expectedCloseDate","notes"]},"unsubscribeFromMarketingEmails":{"verb":"GET","url":"/api/v1/unsubscribe-from-marketing-emails","args":["emailAddress"]},"getStripeCheckoutSessionUrl":{"verb":"POST","url":"/api/v1/customers/get-stripe-checkout-session-url","args":["quoteId"]},"getLlmGeneratedSql":{"verb":"GET","url":"/api/v1/query-generator/get-llm-generated-sql","args":["naturalLanguageQuestion"]},"getLlmGeneratedConfigurationProfile":{"verb":"POST","url":"/api/v1/get-llm-generated-configuration-profile","args":["profileType","naturalLanguageInstructions"]},"deliverApplicationSubmission":{"verb":"POST","url":"/api/v1/deliver-application-submission","args":["firstName","lastName","emailAddress","position","linkedinProfileUrl","location","message"]},"deliverGitopsWorkshopRequest":{"verb":"POST","url":"/api/v1/deliver-gitops-request","args":["firstName","lastName","emailAddress","location","numberOfHosts","managedPlatforms","willingToHost"]},"resetOneFleetPremiumLocalTrial":{"verb":"POST","url":"/api/v1/admin/reset-one-fleet-premium-local-trial","args":["emailAddress"]},"deliverWhitepaperDownloadRequest":{"verb":"POST","url":"/api/v1/deliver-whitepaper-download-request","args":["firstName","lastName","emailAddress","whitepaperName"]},"deliverPartnerRegistrationSubmission":{"verb":"POST","url":"/api/v1/deliver-partner-registration-submission","args":[]},"createCompliancePartnerTenant":{"verb":"POST","url":"/api/v1/microsoft-compliance-partner","args":["entraTenantId"]},"getCompliancePartnerSettings":{"verb":"GET","url":"/api/v1/microsoft-compliance-partner/settings","args":["entraTenantId","fleetServerSecret"]},"removeOneCompliancePartnerTenant":{"verb":"DELETE","url":"/api/v1/microsoft-compliance-partner","args":["entraTenantId","fleetServerSecret"]},"updateOneDevicesComplianceStatus":{"verb":"POST","url":"/api/v1/microsoft-compliance-partner/device","args":["entraTenantId","fleetServerSecret","deviceId","deviceManagementState","deviceName","os","osVersion","userPrincipalName","compliant","lastCheckInTime"]},"getOneComplianceStatusResult":{"verb":"GET","url":"/api/v1/microsoft-compliance-partner/device/message","args":["entraTenantId","fleetServerSecret","messageId"]},"receiveRedirectFromMicrosoft":{"verb":"GET","url":"/api/v1/microsoft-compliance-partner/adminconsent","args":["tenant","state","error","error_description"]},"registerOneFleetInstanceUsingVpp":{"verb":"POST","url":"/api/vpp/v1/auth","args":["fleetServerUrl","fleetLicenseKey"]},"getVppAppMetadata":{"verb":"GET","url":"/api/vpp/v1/metadata/:storeRegion","args":["storeRegion","platform","additionalPlatforms","ids","extend"]}} + methods: {"redirectToStripeBillingPortal":{"verb":"GET","url":"/customers/update-subscription","args":[]},"downloadSitemap":{"verb":"GET","url":"/sitemap.xml","args":[]},"downloadRssFeed":{"verb":"GET","url":"/rss/:categoryName","args":["categoryName"]},"receiveUsageAnalytics":{"verb":"POST","url":"/api/v1/webhooks/receive-usage-analytics","args":["anonymousIdentifier","fleetVersion","licenseTier","numHostsEnrolled","numUsers","numTeams","numPolicies","numLabels","softwareInventoryEnabled","vulnDetectionEnabled","systemUsersEnabled","hostsStatusWebHookEnabled","numWeeklyActiveUsers","numWeeklyPolicyViolationDaysActual","numWeeklyPolicyViolationDaysPossible","hostsEnrolledByOperatingSystem","hostsEnrolledByOrbitVersion","hostsEnrolledByOsqueryVersion","storedErrors","numHostsNotResponding","organization","mdmMacOsEnabled","mdmWindowsEnabled","liveQueryDisabled","hostExpiryEnabled","numSoftwareVersions","numHostSoftwares","numSoftwareTitles","numHostSoftwareInstalledPaths","numSoftwareCPEs","numSoftwareCVEs","aiFeaturesDisabled","maintenanceWindowsEnabled","maintenanceWindowsConfigured","numHostsFleetDesktopEnabled","numQueries","numHostsABMPending","fleetMaintainedAppsWindows","fleetMaintainedAppsMacOS","oktaConditionalAccessConfigured","entraConditionalAccessConfigured","conditionalAccessBypassDisabled","conditionalAccessEnabled"]},"receiveFromGithub":{"verb":"GET","url":"/api/v1/webhooks/github","args":["botSignature","action","sender","repository","changes","issue","comment","pull_request","label","release","projects_v2_item"]},"receiveFromStripe":{"verb":"POST","url":"/api/v1/webhooks/receive-from-stripe","args":["id","type","data","webhookSecret"]},"receiveFromZapier":{"verb":"POST","url":"/api/v1/webhooks/receive-from-zapier","args":["eventName","data","webhookSecret"]},"receiveFromClay":{"verb":"POST","url":"/api/v1/webhooks/receive-from-clay","args":["webhookSecret","firstName","lastName","linkedinUrl","emailAddress","contactSource","jobTitle","intentSignal","historicalContent","historicalContentUrl","relatedCampaign"]},"getEstDeviceCertificate":{"verb":"POST","url":"/api/v1/get-est-device-certificate","args":["csrData","authToken","introspectEndpoint","idpClientId","estEndpoint","estClientId","estClientKey"]},"createAndroidSignupUrl":{"verb":"POST","url":"/api/android/v1/signupUrls","args":["callbackUrl"]},"createAndroidEnterprise":{"verb":"POST","url":"/api/android/v1/enterprises","args":["signupUrlName","enterpriseToken","fleetLicenseKey","pubsubPushUrl","enterprise"]},"getAndroidEnterprises":{"verb":"GET","url":"/api/android/v1/enterprises","args":[]},"createAndroidEnrollmentToken":{"verb":"POST","url":"/api/android/v1/enterprises/:androidEnterpriseId/enrollmentTokens","args":["androidEnterpriseId"]},"modifyAndroidPolicies":{"verb":"PATCH","url":"/api/android/v1/enterprises/:androidEnterpriseId/policies/:policyId","args":["androidEnterpriseId","policyId"]},"deleteOneAndroidEnterprise":{"verb":"DELETE","url":"/api/android/v1/enterprises/:androidEnterpriseId","args":["androidEnterpriseId"]},"getAndroidDevice":{"verb":"GET","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices/:deviceId","args":["androidEnterpriseId","deviceId"]},"getAndroidDevices":{"verb":"GET","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices","args":["androidEnterpriseId","pageSize","pageToken","fields"]},"deleteAndroidDevice":{"verb":"DELETE","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices/:deviceId","args":["androidEnterpriseId","deviceId"]},"modifyAndroidDevice":{"verb":"PATCH","url":"/api/android/v1/enterprises/:androidEnterpriseId/devices/:deviceId","args":["androidEnterpriseId","deviceId"]},"getEnterpriseApplications":{"verb":"GET","url":"/api/android/v1/enterprises/:androidEnterpriseId/applications/:applicationId","args":["androidEnterpriseId","applicationId"]},"modifyEnterpriseAppPolicy":{"verb":"POST","url":"/api/android/v1/enterprises/:androidEnterpriseId/policies/:policyId::googleAction","args":["androidEnterpriseId","policyId","googleAction","packageNames","changes"]},"createEnterpriseWebapp":{"verb":"POST","url":"/api/android/v1/enterprises/:androidEnterpriseId/webApps","args":["androidEnterpriseId","title","startUrl","icons","displayMode","versionCode"]},"deliverContactFormMessage":{"verb":"POST","url":"/api/v1/deliver-contact-form-message","args":["emailAddress","firstName","lastName","message"]},"sendPasswordRecoveryEmail":{"verb":"POST","url":"/api/v1/entrance/send-password-recovery-email","args":["emailAddress"]},"signup":{"verb":"POST","url":"/api/v1/customers/signup","args":["emailAddress","password","organization","firstName","lastName","signupReason"]},"updateProfile":{"verb":"POST","url":"/api/v1/account/update-profile","args":["firstName","lastName","organization","emailAddress"]},"updatePassword":{"verb":"POST","url":"/api/v1/account/update-password","args":["oldPassword","newPassword"]},"updateBillingCard":{"verb":"POST","url":"/api/v1/account/update-billing-card","args":["stripeToken","billingCardLast4","billingCardBrand","billingCardExpMonth","billingCardExpYear"]},"login":{"verb":"POST","url":"/api/v1/customers/login","args":["emailAddress","password","rememberMe"]},"logout":{"verb":"GET","url":"/api/v1/account/logout","args":[]},"createQuote":{"verb":"POST","url":"/api/v1/customers/create-quote","args":["macosHosts","windowsHosts","linuxHosts","iosHosts","androidHosts","otherHosts"]},"saveBillingInfoAndSubscribe":{"verb":"POST","url":"/api/v1/customers/save-billing-info-and-subscribe","args":["quoteId","organization","firstName","lastName","paymentSource"]},"updatePasswordAndLogin":{"verb":"POST","url":"/api/v1/entrance/update-password-and-login","args":["password","token"]},"deliverDemoSignup":{"verb":"POST","url":"/api/v1/deliver-demo-signup","args":["emailAddress"]},"createOrUpdateOneNewsletterSubscription":{"verb":"POST","url":"/api/v1/create-or-update-one-newsletter-subscription","args":["emailAddress"]},"unsubscribeFromAllNewsletters":{"verb":"GET","url":"/api/v1/unsubscribe-from-all-newsletters","args":["emailAddress"]},"buildLicenseKey":{"verb":"POST","url":"/api/v1/admin/build-license-key","args":["numberOfHosts","organization","expiresAt","partnerName"]},"createVantaAuthorizationRequest":{"verb":"POST","url":"/api/v1/create-vanta-authorization-request","args":["emailAddress","fleetInstanceUrl","fleetApiKey","redirectToExternalPageAfterAuthorization","sharedSecret"]},"redirectVantaAuthorizationRequest":{"verb":"GET","url":"/redirect-vanta-authorization-request","args":["vantaSourceId","state","vantaAuthorizationRequestURL","redirectAfterSetup"]},"deliverMdmBetaSignup":{"verb":"POST","url":"/api/v1/deliver-mdm-beta-signup","args":["emailAddress","fullName","jobTitle","numberOfHosts"]},"getHumanInterpretationFromOsquerySql":{"verb":"POST","url":"/api/v1/get-human-interpretation-from-osquery-sql","args":["sql"]},"deliverAppleCsr":{"verb":"POST","url":"/api/v1/deliver-apple-csr","args":["unsignedCsrData","deliveryMethod"]},"deliverMdmDemoEmail":{"verb":"POST","url":"/api/v1/deliver-mdm-demo-email","args":["emailAddress"]},"provisionSandboxInstanceAndDeliverEmail":{"verb":"POST","url":"/api/v1/admin/provision-sandbox-instance-and-deliver-email","args":["userId"]},"deliverTalkToUsFormSubmission":{"verb":"POST","url":"/api/v1/deliver-talk-to-us-form-submission","args":["emailAddress","firstName","lastName","organization","numberOfHosts","primaryBuyingSituation"]},"saveQuestionnaireProgress":{"verb":"POST","url":"/api/v1/save-questionnaire-progress","args":["currentStep","formData"]},"updateStartCtaVisibility":{"verb":"POST","url":"/api/v1/account/update-start-cta-visibility","args":[]},"deliverDealRegistrationSubmission":{"verb":"POST","url":"/api/v1/deliver-deal-registration-submission","args":["submittersFirstName","submittersLastName","submittersEmailAddress","submittersOrganization","submitterIsExistingPartner","customersOrganization","customersName","customersEmailAddress","dealStage","expectedClose","numberOfHosts","platforms","useCase","notes"]},"unsubscribeFromMarketingEmails":{"verb":"GET","url":"/api/v1/unsubscribe-from-marketing-emails","args":["emailAddress"]},"getStripeCheckoutSessionUrl":{"verb":"POST","url":"/api/v1/customers/get-stripe-checkout-session-url","args":["quoteId"]},"getLlmGeneratedSql":{"verb":"GET","url":"/api/v1/query-generator/get-llm-generated-sql","args":["naturalLanguageQuestion"]},"getLlmGeneratedConfigurationProfile":{"verb":"POST","url":"/api/v1/get-llm-generated-configuration-profile","args":["profileType","naturalLanguageInstructions"]},"deliverApplicationSubmission":{"verb":"POST","url":"/api/v1/deliver-application-submission","args":["firstName","lastName","emailAddress","position","linkedinProfileUrl","location","message"]},"deliverGitopsWorkshopRequest":{"verb":"POST","url":"/api/v1/deliver-gitops-request","args":["firstName","lastName","emailAddress","location","numberOfHosts","managedPlatforms","willingToHost"]},"resetOneFleetPremiumLocalTrial":{"verb":"POST","url":"/api/v1/admin/reset-one-fleet-premium-local-trial","args":["emailAddress"]},"deliverWhitepaperDownloadRequest":{"verb":"POST","url":"/api/v1/deliver-whitepaper-download-request","args":["firstName","lastName","emailAddress","whitepaperName"]},"deliverWebinarAccessRequest":{"verb":"POST","url":"/api/v1/deliver-webinar-access-request","args":["firstName","lastName","emailAddress","webinarName"]},"deliverPartnerRegistrationSubmission":{"verb":"POST","url":"/api/v1/deliver-partner-registration-submission","args":["submittersFirstName","submittersLastName","submittersEmailAddress","submittersOrganization","partnerType","partnerWebsite","partnerCountry","notes","servicesOffered","numberOfHosts","servicesCategory"]},"createCompliancePartnerTenant":{"verb":"POST","url":"/api/v1/microsoft-compliance-partner","args":["entraTenantId"]},"getCompliancePartnerSettings":{"verb":"GET","url":"/api/v1/microsoft-compliance-partner/settings","args":["entraTenantId","fleetServerSecret"]},"removeOneCompliancePartnerTenant":{"verb":"DELETE","url":"/api/v1/microsoft-compliance-partner","args":["entraTenantId","fleetServerSecret"]},"updateOneDevicesComplianceStatus":{"verb":"POST","url":"/api/v1/microsoft-compliance-partner/device","args":["entraTenantId","fleetServerSecret","deviceId","deviceManagementState","deviceName","os","osVersion","userPrincipalName","compliant","lastCheckInTime"]},"getOneComplianceStatusResult":{"verb":"GET","url":"/api/v1/microsoft-compliance-partner/device/message","args":["entraTenantId","fleetServerSecret","messageId"]},"receiveRedirectFromMicrosoft":{"verb":"GET","url":"/api/v1/microsoft-compliance-partner/adminconsent","args":["tenant","state","error","error_description"]},"registerOneFleetInstanceUsingVpp":{"verb":"POST","url":"/api/vpp/v1/auth","args":["fleetServerUrl","fleetLicenseKey"]},"getVppAppMetadata":{"verb":"GET","url":"/api/vpp/v1/metadata/:storeRegion","args":["storeRegion","platform","additionalPlatforms","ids","extend"]}} /* eslint-enable */ }); diff --git a/website/assets/js/pages/articles/basic-webinar.page.js b/website/assets/js/pages/articles/basic-webinar.page.js new file mode 100644 index 0000000000..9dda34d79c --- /dev/null +++ b/website/assets/js/pages/articles/basic-webinar.page.js @@ -0,0 +1,76 @@ +parasails.registerPage('basic-webinar', { + // ╦╔╗╔╦╔╦╗╦╔═╗╦ ╔═╗╔╦╗╔═╗╔╦╗╔═╗ + // ║║║║║ ║ ║╠═╣║ ╚═╗ ║ ╠═╣ ║ ║╣ + // ╩╝╚╝╩ ╩ ╩╩ ╩╩═╝ ╚═╝ ╩ ╩ ╩ ╩ ╚═╝ + data: { + formData: { + emailAddress: undefined, + firstName: undefined, + lastName: undefined, + }, + formRules: { + emailAddress: {isEmail: true, required: true}, + firstName: {required: true}, + lastName: {required: true}, + }, + formDataToPrefillForLoggedInUsers: {}, + formErrors: {}, + syncing: false, + cloudError: '', + cloudSuccess: '', + scrollDistance: undefined, + }, + + // ╦ ╦╔═╗╔═╗╔═╗╦ ╦╔═╗╦ ╔═╗ + // ║ ║╠╣ ║╣ ║ ╚╦╝║ ║ ║╣ + // ╩═╝╩╚ ╚═╝╚═╝ ╩ ╚═╝╩═╝╚═╝ + beforeMount: function() { + if(this.me){// prefill from database + this.formDataToPrefillForLoggedInUsers.emailAddress = this.me.emailAddress; + this.formDataToPrefillForLoggedInUsers.firstName = this.me.firstName; + this.formDataToPrefillForLoggedInUsers.lastName = this.me.lastName; + this.formData = _.clone(this.formDataToPrefillForLoggedInUsers); + } + }, + mounted: async function() { + this.formData.webinarName = this.thisPage.meta.articleTitle; + + // Add an event listener to add a class to the right sidebar when the header is hidden. + window.addEventListener('scroll', this.handleScrollingInArticle); + }, + + // ╦╔╗╔╔╦╗╔═╗╦═╗╔═╗╔═╗╔╦╗╦╔═╗╔╗╔╔═╗ + // ║║║║ ║ ║╣ ╠╦╝╠═╣║ ║ ║║ ║║║║╚═╗ + // ╩╝╚╝ ╩ ╚═╝╩╚═╩ ╩╚═╝ ╩ ╩╚═╝╝╚╝╚═╝ + methods: { + submittedDownloadForm: async function () { + if(typeof qualified !== 'undefined') { + qualified('saveFormData', + { + email: this.formData.emailAddress, + name: this.formData.firstName+' '+this.formData.lastName, + }); + qualified('showFormExperience', 'experience-1772126772950'); + } + this.syncing = true; + this.goto(this.thisPage.url+'/watch'); + }, + handleScrollingInArticle: function () { + let rightNavBar = document.querySelector('div[purpose="right-sidebar"]'); + let scrollTop = window.pageYOffset; + let windowHeight = window.innerHeight; + // Add/remove the 'header-hidden' class to the right sidebar to scroll it upwards with the website's header. + if (rightNavBar) { + if (scrollTop > this.scrollDistance && scrollTop > windowHeight * 1.5) { + rightNavBar.classList.add('header-hidden'); + this.lastScrollTop = scrollTop; + } else if(scrollTop < this.lastScrollTop - 60) { + rightNavBar.classList.remove('header-hidden'); + this.lastScrollTop = scrollTop; + } + } + this.scrollDistance = scrollTop; + }, + } +}); + diff --git a/website/assets/styles/importer.less b/website/assets/styles/importer.less index 189e4ed173..895eec0c15 100644 --- a/website/assets/styles/importer.less +++ b/website/assets/styles/importer.less @@ -108,3 +108,4 @@ @import 'pages/articles/basic-whitepaper.less'; @import 'pages/landing-pages/replace-jamf.less'; @import 'pages/partners.less'; +@import 'pages/articles/basic-webinar.less'; diff --git a/website/assets/styles/pages/articles/basic-webinar.less b/website/assets/styles/pages/articles/basic-webinar.less new file mode 100644 index 0000000000..f6125c533b --- /dev/null +++ b/website/assets/styles/pages/articles/basic-webinar.less @@ -0,0 +1,749 @@ +#basic-webinar { + h1 { + font-size: 36px; + } + hr { + margin-top: 40px; + margin-bottom: 40px; + border-top: 2px solid @core-vibrant-blue-15; + width: 100%; + } + .markdown-heading:hover { + .markdown-link { + height: 16px; + vertical-align: middle; + margin-left: 8px; + content: url('/images/icon-link-green-16x16@2x.png'); + } + } + + @keyframes copiedText { + 0% {opacity: 0;} + 20% {opacity: 100;} + 30% {opacity: 80;} + 50% {opacity: 60;} + 70% {opacity: 40;} + 80% {opacity: 20;} + 100% {opacity: 0;} + } + + [purpose='page-container'] { + max-width: 1200px; + padding: 64px; + } + [purpose='embedded-video'] { + position: relative; + margin-bottom: 40px; + width: 100%; + padding-bottom: 56%; + border-radius: 12px; + iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + border: none; + // border-radius: 12px; + } + [purpose='video-note'] { + position: absolute; + bottom: 0; + max-width: 480px; + margin-left: auto; + margin-right: auto; + padding: 16px; + border-radius: 8px; + border: 1px solid #E6E3D0; + background: #FFFEF9; + p { + margin-bottom: 0px; + } + } + + } + [purpose='right-sidebar'] { + position: sticky; + top: 144px; + width: 392px; + font-size: 14px; + transition-property: transform; + transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1); + transition-duration: 500ms; + } + [purpose='form-container'] { + border-radius: 16px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + padding: 32px; + background: #F8F8F8; + h4 { + color: #192147; + /* Heading/H4 */ + font-family: Inter; + font-size: 20px; + font-style: normal; + font-weight: 700; + line-height: 120%; + margin-bottom: 0px; + } + } + [purpose='webinar-recording-form'] { + display: flex; + scroll-margin-top: 130px; + flex-direction: column; + justify-content: center; + align-items: flex-start; + gap: 32px; + + label { + color: #192147; + + /* Body SM (bold) */ + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 150%; + } + input { + display: flex; + height: 36px; + padding: 0 12px; + align-items: center; + gap: 8px; + align-self: stretch; + border-radius: 6px; + border: 1px solid #C5C7D1; + background: #FFF; + } + } + + [purpose='watch-button'] { + display: flex; + height: 36px; + padding: 16px 12px; + justify-content: center; + align-items: center; + gap: 4px; + flex: 1 0 0; + color: #FFF; + text-align: center; + + /* Body SM (bold) */ + font-family: Inter; + font-size: 14px; + font-style: normal; + font-weight: 700; + line-height: 150%; + width: 100%; + } + [purpose='watch-cta'] { + display: flex; + flex-direction: column; + align-items: center; + [purpose='watch-button'] { + max-width: 255px; + + } + } + .header-hidden { // For scrolling the sidebar with the sticky header + transform: translateY(-120px); + } + [purpose='article-container'] { + max-width: 800px; + padding-right: 64px; + display: flex; + flex-direction: column; + min-width: 0px; + } + [purpose='article-title-and-image'] { + display: flex; + flex-direction: row; + gap: 64px; + align-items: center; + } + [purpose='article-image'] { + width: calc(~'50% - 32px'); + img { + height: auto; + width: 100%; + } + } + [purpose='article-title-and-introduction'] { + width: 50%; + padding-top: 64px; + margin-bottom: 64px; + display: flex; + flex-direction: column; + gap: 32px; + h1 { + color: #192147; + + /* Heading/H1 */ + font-family: Inter; + font-size: 48px; + font-style: normal; + font-weight: 800; + line-height: 120%; + margin-bottom: 0px; + } + + h2 { + font-size: 24px; + font-weight: 400; + line-height: 32px; + } + h4 { + color: #515774; + font-feature-settings: 'salt' on, 'ss01' on, 'ss02' on; + font-family: 'Roboto Mono'; + font-size: 16px; + font-style: normal; + font-weight: 400; + line-height: 150%; + text-transform: uppercase; + margin-bottom: 0px; + margin-top: 0px; + } + [purpose='article-introduction'] { + display: flex; + flex-direction: column; + gap: 32px; + p { + margin-bottom: 0px; + } + + } + } + + [purpose='article-content'] { + word-wrap: break-word; + h1:first-of-type { + display: none; + } + h1:first-of-type + h2:first-of-type { + display: none; + } + img { + max-width: 100%; + width: auto; + height: auto; + max-height: 100%; + margin-left: auto; + margin-right: auto; + padding: 24px 0px 16px 0px; + } + h2 { + color: #192147; + + /* Heading/H2 */ + font-family: Inter; + font-size: 32px; + font-style: normal; + font-weight: 800; + line-height: 120%; + margin-bottom: 32px; + } + h3 { + color: #192147; + + /* Heading/H3 */ + font-family: Inter; + font-size: 24px; + font-style: normal; + font-weight: 800; + line-height: 120%; + margin-top: 40px; + margin-bottom: 32px; + } + h4 { + font-size: 16px; + margin-top: 24px; + margin-bottom: 24px; + } + h2 > code:not(.bash):not(.nohighlight):not(.mermaid) { + padding: 0px 4px; + font-weight: 400; + font-size: 22px; + line-height: inherit; + } + h3 > code:not(.bash):not(.nohighlight):not(.mermaid) { + padding: 0px 4px; + font-weight: 400; + font-size: 18px; + line-height: inherit; + } + p { + font-size: 16px; + line-height: 150%; + color: #515774; + margin-bottom: 32px; + } + img + em { // Image captions + position: relative; + top: -12px; + display: flex; + align-items: center; + flex-direction: column; + margin-bottom: 16px; + } + ul, ol { + padding-left: 16px; + } + li { + // padding-bottom: 16px; + } + li::marker { + color: #515774; + } + .markdown-heading { + scroll-margin-top: 140px; + } + [purpose='checklist-item'] { + display: flex; + input[type='checkbox'] { + margin-left: -18px; + min-width: 16px; + min-height: 16px; + align-self: center; + } + input:checked, input:active { + accent-color: @core-vibrant-blue; + } + [purpose='task'] { + margin-left: 16px; + input { + display: none; + } + p { + margin-bottom: 0px; + } + } + } + [purpose='checklist-item']::marker { + display: none; + } + ul { + list-style-type: disc; + padding-left: 16px; + margin-bottom: 32px; + } + li { + line-height: 24px; + // padding-bottom: 16px; + p { // Making sure our list items stay a consistent size if the contents get wrapped in a

tag coverted from Markdown. + margin-bottom: 0; + } + ol, ul { // adding padding to nested lists + padding-top: 16px; + li:last-child { // removing the padding from the last item of nested lists + padding-bottom: 0px; + } + } + } + ol { + counter-reset: custom-counter; + list-style-type: none; + padding-inline-start: 0px; + padding: 0; + margin-top: 16px; + margin-bottom: 20px; + ul > li { + text-indent: 0px; + margin-left: 0px; + } + > li { + counter-increment: custom-counter; + margin-left: 36px; + text-indent: -36px; + padding-left: 0px; + margin-bottom: 16px; + code:not(.nohighlight):not(.mermaid) { + display: inline; + } + p { + display: inline; + margin-bottom: 0px; + } + blockquote { + text-indent: 0px; + } + } + > li::before { + content: counter(custom-counter); + background-color: #E2E4EA; + width: 24px; + font-size: 13px; + display: inline-block; + border-radius: 50%; + margin-right: 10px; + padding: 2px 4px; + text-align: center; + line-height: 20px; + text-indent: 0px; + } + } + a > code:not(.hljs):not(.nohighlight):not(.mermaid) { + color: inherit; + text-decoration: inherit; + } + code:not(.bash):not(.hljs):not(.nohighlight):not(.mermaid) { + background: #F1F0FF; + padding: 4px 8px; + font-family: @code-font; + font-size: 13px; + line-height: 16px; + color: @core-fleet-black; + } + pre { + code { + background: none; + padding: 0px; + font-family: @code-font; + font-size: 13px; + line-height: 16px; + color: @core-fleet-black; + } + padding: 24px; + border: 1px solid #E2E4EA; + border-radius: 6px; + margin: 0px 0px 40px; + font-family: @code-font; + background: #F9FAFC; + white-space: break-spaces; + } + code.mermaid:not([data-processed='true']) { + opacity: 0; + } + code.mermaid { + color: @core-fleet-black-75; + margin-bottom: 16px; + font-family: @code-font; + display: inline-block; + margin-left: auto; + margin-right: auto; + background: #fff; + svg { + max-height: 600px; + } + } + blockquote { + display: block; + position: relative; + } + [purpose='quote'] { + margin: 72px 0 32px 0px; + font-style: italic; + line-height: 150%; + font-size: 20px; + max-width: 640px; + p { + margin-top: 8px; + } + } + [purpose='large-quote'] { + margin: 72px 0 32px 0px; + font-style: italic; + line-height: 150%; + margin-bottom: 24px; + font-size: 16px; + p:last-of-type { + margin-bottom: 0px; + } + strong { + color: #515774; + font-family: Inter; + font-size: 12px; + font-style: normal; + font-weight: 700; + line-height: 18px; + } + } + [purpose='large-quote']::before, [purpose='quote']::before { + content: ' '; + background-image: url('/images/icon-quote-21x17@2x.png'); + background-repeat: no-repeat; + background-size: 21px 17px; + display: block; + position: relative; + top: -16px; + left: 0px; + width: 21px; + height: 17px; + } + [purpose='attribution-quote'], [purpose='large-quote'] { + margin: 72px 0 32px 0px; + p { + font-style: italic; + line-height: 150%; + margin-bottom: 24px; + font-size: 20px; + } + p:last-of-type { + margin-bottom: 0px; + } + strong { + color: #515774; + font-family: Inter; + font-size: 12px; + font-style: normal; + font-weight: 700; + line-height: 18px; + } + } + [purpose='attribution-quote']::before { + content: ' '; + background-image: url('/images/icon-quote-21x17@2x.png'); + background-repeat: no-repeat; + background-size: 21px 17px; + display: block; + position: relative; + top: -16px; + left: 0px; + width: 21px; + height: 17px; + } + [purpose='checklist'] { + margin-bottom: 32px; + p { + font-size: 16px; + line-height: 150%; + font-style: normal; + font-weight: 400; + padding-left: 40px; + text-indent: -40px; + margin-bottom: 16px; + padding-top: 12px; + padding-bottom: 12px; + &:last-of-type { + margin-bottom: 0px; + } + } + p::before { + content: ' '; + background-image: url('/images/icon-checkbox-checked-24x24@2x.png'); + background-size: 24px 24px; + display: inline-block; + position: relative; + top: 7px; + margin-right: 16px; + width: 24px; + height: 24px; + } + } + [purpose='tip'] { + margin: 16px 0 32px; + background: #F7F7FC; + border: 1px solid @core-vibrant-blue-50; + padding: 16px; + border-radius: 8px; + display: flex; + img { + display: flex; + margin: 4px 12px 0 0; + height: 16px; + width: 16px; + padding: 0px; + } + p { + display: block; + margin-bottom: 16px; + line-height: 24px; + font-size: 16px; + } + p:only-child, p:last-child { + margin-bottom: 0px; + } + ul:last-child { + margin-bottom: 0px; + } + li:last-child { + padding-bottom: 0px; + } + :first-child {// Remove top padding from the first element inside purpose="tip" blockquotes + padding-top: 0; + } + } + [purpose='embedded-content'] { + position: relative; + margin-bottom: 40px; + width: 100%; + padding-bottom: 57%; + iframe { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + } + [purpose='embedded-document'] { + margin-bottom: 40px; + width: 100%; + height: 800px; + } + table { + table-layout: auto; + border: 1px solid @border-lt-gray; + border-collapse: collapse; + font-size: 16px; + line-height: 28px; + margin-bottom: 16px; + max-width: 100%; + th { + font-weight: @bold; + border: 1px solid @border-lt-gray; + padding: 8px 7px 7px 8px; + } + td { + border: 1px solid @border-lt-gray; + padding: 8px 7px 7px 8px; + } + } + } + [purpose='social-share-and-edit-buttons'] { + padding-top: 24px; + margin-top: 64px; + border-top: 1px solid #E2E4EA; + [purpose='social-share-buttons'] { + gap: 16px; + img { + width: 20px; + height: 20px; + padding: 0; + } + } + [purpose='edit-link'] { + a { + font-size: 14px; + line-height: 20px; + display: flex; + flex-direction: row; + align-items: center; + gap: 12px; + text-decoration: none; + img { + width: 16px; + padding: 0; + height: 16px; + } + } + + } + + + } + + @media (max-width: 991px) { + [purpose='page-container'] { + max-width: 1200px; + padding: 48px; + } + [purpose='right-sidebar'] { + margin-top: 64px; + margin-bottom: 48px; + width: 100%; + } + .header-hidden { + transform: translateY(0); + } + + [purpose='article-container'] { + max-width: 100%; + padding-right: 0px; + display: flex; + flex-direction: column; + } + [purpose='article-content'] { + padding-bottom: 0px; + } + [purpose='webinar-recording-form'] { + max-width: 324px; + } + [purpose='article-title-and-introduction'] { + margin-bottom: 0px; + padding-top: 0px; + width: 100%; + } + [purpose='article-title-and-image'] { + display: flex; + flex-direction: column; + gap: 48px; + justify-content: center; + align-items: center; + } + [purpose='article-image'] { + width: 100%; + img { + height: unset; + width: 100%; + } + } + } + + @media (max-width: 769px) { + [purpose='article-title'] { + padding-top: 40px; + margin-bottom: 8px; + h1 { + font-size: 28px; + line-height: 38px; + } + } + [purpose='article-content'] { + img { + padding-bottom: 0px; + } + img + em { // Image captions + top: 4px; + margin-bottom: 16px; + } + } + + } + @media (max-width: 575px) { + [purpose='page-container'] { + padding: 32px 24px; + } + [purpose='article-title-and-introduction'] { + h1 { + color: #192147; + + /* Heading/H1 */ + font-family: Inter; + font-size: 32px; + font-style: normal; + font-weight: 800; + line-height: 120%; + } + + } + [purpose='article-content'] { + h2 { + color: #192147; + + /* Heading/H2 */ + font-family: Inter; + font-size: 24px; + font-style: normal; + font-weight: 800; + line-height: 120%; + } + h3 { + color: #192147; + + /* Heading/H3 */ + font-family: Inter; + font-size: 20px; + font-style: normal; + font-weight: 800; + line-height: 120%; + } + } + } + +} diff --git a/website/config/policies.js b/website/config/policies.js index 448fff8115..fc98f82e9f 100644 --- a/website/config/policies.js +++ b/website/config/policies.js @@ -77,4 +77,5 @@ module.exports.policies = { 'deliver-whitepaper-download-request': true, 'deliver-partner-registration-submission': true, 'view-partners': true, + 'deliver-webinar-access-request': true, }; diff --git a/website/config/routes.js b/website/config/routes.js index b20a2a6bdf..55710812c9 100644 --- a/website/config/routes.js +++ b/website/config/routes.js @@ -626,6 +626,23 @@ module.exports.routes = { } }, + + 'GET /webinars/:slug': { + action: 'articles/view-basic-webinar', + locals: { + displayVideo: false, + } + }, + + 'GET /webinars/:slug/watch': { + action: 'articles/view-basic-webinar', + locals: { + displayVideo: true, + disableChatbotAndIndexing: true, + hideFooterLinks: true, + } + }, + // ╦ ╔═╗╔═╗╔═╗╔═╗╦ ╦ ╦═╗╔═╗╔╦╗╦╦═╗╔═╗╔═╗╔╦╗╔═╗ // ║ ║╣ ║ ╦╠═╣║ ╚╦╝ ╠╦╝║╣ ║║║╠╦╝║╣ ║ ║ ╚═╗ // ╩═╝╚═╝╚═╝╩ ╩╚═╝ ╩ ╩╚═╚═╝═╩╝╩╩╚═╚═╝╚═╝ ╩ ╚═╝ @@ -1351,6 +1368,7 @@ module.exports.routes = { 'POST /api/v1/deliver-gitops-request': { action: 'deliver-gitops-workshop-request' }, 'POST /api/v1/admin/reset-one-fleet-premium-local-trial': { action: 'admin/reset-one-fleet-premium-local-trial' }, 'POST /api/v1/deliver-whitepaper-download-request': { action: 'deliver-whitepaper-download-request' }, + 'POST /api/v1/deliver-webinar-access-request': { action: 'deliver-webinar-access-request' }, 'POST /api/v1/deliver-partner-registration-submission': { action: 'deliver-partner-registration-submission' }, // ╔╦╗╦╔═╗╦═╗╔═╗╔═╗╔═╗╔═╗╔╦╗ ╔═╗╦═╗╔═╗═╗ ╦╦ ╦ ╔═╗╔╗╔╔╦╗╔═╗╔═╗╦╔╗╔╔╦╗╔═╗ diff --git a/website/scripts/build-static-content.js b/website/scripts/build-static-content.js index 945c84159d..10988c3ffb 100644 --- a/website/scripts/build-static-content.js +++ b/website/scripts/build-static-content.js @@ -666,7 +666,7 @@ module.exports = { throw new Error(`Failed compiling markdown content: An article page is missing a category meta tag () at "${path.join(topLvlRepoPath, pageSourcePath)}". To resolve, add a meta tag with the category of the article`); } else { // Throwing an error if the article has an invalid category. - let validArticleCategories = ['deploy', 'articles', 'security', 'engineering', 'success stories', 'announcements', 'guides', 'releases', 'podcasts', 'report', 'case study', 'comparison', 'whitepaper' ]; + let validArticleCategories = ['deploy', 'articles', 'security', 'engineering', 'success stories', 'announcements', 'guides', 'releases', 'podcasts', 'report', 'case study', 'comparison', 'whitepaper', 'webinar' ]; if(!validArticleCategories.includes(embeddedMetadata.category)) { throw new Error(`Failed compiling markdown content: An article page has an invalid category meta tag () at "${path.join(topLvlRepoPath, pageSourcePath)}". To resolve, change the meta tag to a valid category, one of: ${validArticleCategories}`); } @@ -764,6 +764,22 @@ module.exports = { } } } + // If this is a webinar article, we'll check to make sure it has a webinarEmbeddedVideoUrl meta tag. + if(embeddedMetadata.category === 'webinar') { + if(!embeddedMetadata.webinarEmbeddedVideoUrl){ + throw new Error(`Failed compiling markdown content: A webinar article is missing a 'webinarEmbeddedVideoUrl' meta tag at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, add a webinarEmbeddedVideoUrl meta tag with a value that is the URL of the webinar this article is presenting, and try running this script again.`); + } else { + let parsedVideoUrl; + try { + parsedVideoUrl = URL.parse(embeddedMetadata.webinarEmbeddedVideoUrl); + } catch(err) { + throw new Error(`Failed compiling markdown content: A webinar article has an invalid "webinarEmbeddedVideoUrl" value (${embeddedMetadata.webinarEmbeddedVideoUrl}) at ${path.join(topLvlRepoPath, pageSourcePath)}. Please change this value to be a valid URL of the webinar recording with no query strings.`, err); + } + if(parsedVideoUrl.search) { + throw new Error(`Failed compiling markdown content: A webinar article has a "webinarEmbeddedVideoUrl" value that contains query strings (${parsedVideoUrl.search}) at ${path.join(topLvlRepoPath, pageSourcePath)}. To resolve, remove the query strings from this value and try running this script again. `); + } + } + } // If this is a comparison article, we will require a different set of meta tags and will determine the URL of the page using the articleSlugInCategory meta tag. if(embeddedMetadata.category === 'comparison') { if(!embeddedMetadata.articleSlugInCategory){ @@ -780,7 +796,7 @@ module.exports = { // If the article is categorized as 'product' we'll replace the category with 'use-cases', or if it is categorized as 'success story' we'll replace it with 'device-management' rootRelativeUrlPath = ( '/' + - (encodeURIComponent(embeddedMetadata.category === 'success stories' ? 'success-stories' : embeddedMetadata.category === 'security' ? 'securing' : embeddedMetadata.category === 'whitepaper' ? 'whitepapers' : embeddedMetadata.category === 'case study' ? 'case-study' : embeddedMetadata.category)) + '/' + + (encodeURIComponent(embeddedMetadata.category === 'success stories' ? 'success-stories' : embeddedMetadata.category === 'security' ? 'securing' : embeddedMetadata.category === 'whitepaper' ? 'whitepapers' : embeddedMetadata.category === 'webinar' ? 'webinars' : embeddedMetadata.category === 'case study' ? 'case-study' : embeddedMetadata.category)) + '/' + (pageUnextensionedUnwhitespacedLowercasedRelPath.split(/\//).map((fileOrFolderName) => encodeURIComponent(fileOrFolderName.replace(/^[0-9]+[\-]+/,'').replace(/\./g, '-'))).join('/')) ); } diff --git a/website/views/layouts/layout.ejs b/website/views/layouts/layout.ejs index 0d04f3a8f2..cbe85f87a8 100644 --- a/website/views/layouts/layout.ejs +++ b/website/views/layouts/layout.ejs @@ -889,6 +889,7 @@ + diff --git a/website/views/pages/articles/basic-webinar.ejs b/website/views/pages/articles/basic-webinar.ejs new file mode 100644 index 0000000000..dc9d4c854f --- /dev/null +++ b/website/views/pages/articles/basic-webinar.ejs @@ -0,0 +1,97 @@ +

+ <%if(!displayVideo){%> +
+
+
+
+

Webinar

+

<%=thisPage.meta.articleTitle %>

+
+
+ <%if(thisPage.meta.introductionTextBlockOne){%>

<%- thisPage.meta.introductionTextBlockOne %>

<%}%> + <%if(thisPage.meta.introductionTextBlockTwo){%>

<%- thisPage.meta.introductionTextBlockTwo %>

<%}%> +
+
+ <%if(thisPage.meta.articleImageUrl){%> +
+ A preview image of the webinar +
+ <% } %> +
+
+
+
+
+
+

Sign up to watch the webinar

+ +
+ + +
Please enter your first name.
+
+
+ + +
Please enter your last name.
+
+
+ + +
This doesn’t appear to be a valid email address
+
+ Watch the webinar + +

+ Please enter your work or school email address. +

+
+ + +
+
+
+
+
+
+
+ <%- partial(path.relative(path.dirname(__filename), path.resolve( sails.config.appPath, path.join(sails.config.builtStaticContent.compiledPagePartialsAppPath, thisPage.htmlId)))) %> + +
+

About Fleet

+ +

Fleet is the single endpoint management platform for macOS, iOS, Android, Windows, Linux, ChromeOS, and cloud infrastructure. Trusted by over 1,300 organizations, Fleet empowers IT and security teams to accelerate productivity, build verifiable trust, and optimize costs.

+ +

By bringing infrastructure-as-code (IaC) practices to device management, Fleet ensures endpoints remain secure and operational, freeing engineering teams to focus on strategic initiatives.

+ +

Fleet offers total deployment flexibility: on-premises, air-gapped, container-native (Docker and Kubernetes), or cloud-agnostic (AWS, Azure, GCP, DigitalOcean). Organizations can also choose fully managed SaaS via Fleet Cloud, ensuring complete control over data residency and legal jurisdiction.

+
+
+
+ Share this article on Hacker News + Share this article on LinkedIn + Share this article on Twitter +
+ +
+
+
+
+
+ <%} else {%> +
+
+

<%= thisPage.meta.articleTitle %>

+
+ +
+
+ +
+ <%}%> +
+<%- /* Expose server-rendered data as window.SAILS_LOCALS :: */ exposeLocalsToBrowser() %>