From 18ea764b3cb3f8db32d3dac72ff490f01a0f5f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cyndira-flowforge=E2=80=9D?= <“yndira@flowforge.com”> Date: Tue, 14 May 2024 17:06:51 +0200 Subject: [PATCH 1/3] Implemented Event Banner Rotation --- .eleventy.js | 2 + package-lock.json | 65 +++++++++---------- package.json | 1 + src/_data/events.yaml | 4 ++ src/_includes/components/events-banner.njk | 74 ++++++++++++++++++---- src/css/style.css | 27 ++++++++ 6 files changed, 128 insertions(+), 45 deletions(-) create mode 100644 src/_data/events.yaml diff --git a/.eleventy.js b/.eleventy.js index 3e85106c02..ee4005677c 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -20,11 +20,13 @@ const schema = require("@quasibit/eleventy-plugin-schema"); const imageHandler = require('./lib/image-handler.js') const site = require("./src/_data/site"); const coreNodeDoc = require("./lib/core-node-docs.js"); +const yaml = require("js-yaml"); // Skip slow optimizations when developing i.e. serve/watch or Netlify deploy preview const DEV_MODE = process.env.ELEVENTY_RUN_MODE !== "build" || process.env.CONTEXT === "deploy-preview" module.exports = function(eleventyConfig) { + eleventyConfig.addDataExtension("yaml", contents => yaml.load(contents)); // Add support for YAML data files eleventyConfig.setUseGitIgnore(false); // Otherwise docs are ignored // Set DEV_MODE_POSTS to true if the context is not 'production' diff --git a/package-lock.json b/package-lock.json index c151175bb3..f6eaca7e1e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@quasibit/eleventy-plugin-schema": "^1.11.0", "@xmldom/xmldom": "^0.8.10", "codeowners": "^5.1.1", + "js-yaml": "^4.1.0", "markdown-it-attrs": "^4.1.6", "xml-js": "^1.6.11" }, @@ -1023,11 +1024,9 @@ "license": "MIT" }, "node_modules/argparse": { - "version": "1.0.10", - "license": "MIT", - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-differ": { "version": "3.0.0", @@ -2019,7 +2018,7 @@ }, "node_modules/ejs": { "version": "3.1.10", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dependencies": { "jake": "^10.8.5" @@ -2195,7 +2194,8 @@ }, "node_modules/esprima": { "version": "4.0.1", - "license": "BSD-2-Clause", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "bin": { "esparse": "bin/esparse.js", "esvalidate": "bin/esvalidate.js" @@ -2651,6 +2651,26 @@ "node": ">=6.0" } }, + "node_modules/gray-matter/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/gray-matter/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/hamljs": { "version": "0.6.2" }, @@ -3342,11 +3362,11 @@ "license": "MIT" }, "node_modules/js-yaml": { - "version": "3.14.1", - "license": "MIT", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -3667,10 +3687,6 @@ "dev": true, "license": "MIT" }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "license": "Python-2.0" - }, "node_modules/maximatch": { "version": "0.1.0", "license": "MIT", @@ -3904,11 +3920,6 @@ "url": "https://opencollective.com/mochajs" } }, - "node_modules/mocha/node_modules/argparse": { - "version": "2.0.1", - "dev": true, - "license": "Python-2.0" - }, "node_modules/mocha/node_modules/brace-expansion": { "version": "2.0.1", "dev": true, @@ -3938,17 +3949,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mocha/node_modules/js-yaml": { - "version": "4.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/mocha/node_modules/minimatch": { "version": "5.0.1", "dev": true, @@ -5902,7 +5902,8 @@ }, "node_modules/sprintf-js": { "version": "1.0.3", - "license": "BSD-3-Clause" + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, "node_modules/ssri": { "version": "8.0.1", diff --git a/package.json b/package.json index 1aab8c9e87..d80c803dbf 100644 --- a/package.json +++ b/package.json @@ -61,6 +61,7 @@ "@quasibit/eleventy-plugin-schema": "^1.11.0", "@xmldom/xmldom": "^0.8.10", "codeowners": "^5.1.1", + "js-yaml": "^4.1.0", "markdown-it-attrs": "^4.1.6", "xml-js": "^1.6.11" } diff --git a/src/_data/events.yaml b/src/_data/events.yaml new file mode 100644 index 0000000000..fe7988d734 --- /dev/null +++ b/src/_data/events.yaml @@ -0,0 +1,4 @@ +- type: "Webinar" + title: "Deploy FlowFuse on Industrial IoT with NCD.io" + buttonText: "Learn more" + link: "/webinars/2024/deploy-flowfuse-on-industrial-iot-with-ncd-io/" \ No newline at end of file diff --git a/src/_includes/components/events-banner.njk b/src/_includes/components/events-banner.njk index bf21ca99cc..21b1b675be 100644 --- a/src/_includes/components/events-banner.njk +++ b/src/_includes/components/events-banner.njk @@ -1,15 +1,63 @@ +{% set colors = ["bg-indigo-700 hover:bg-indigo-600", "bg-indigo-800 hover:bg-indigo-700", "bg-indigo-900 hover:bg-indigo-800"] %} + +
+ + window.onload = function() { + const banners = document.querySelectorAll('.event-banner'); + const container = document.querySelector('.event-banner-container'); + let currentBanner = 0; + + // Change the container color to match the current banner + function changeContainerColor(banner) { + const colorClass = banner.className.match(/bg-\w+-\d+/)[0]; + const hoverColorClass = banner.className.match(/hover:bg-\w+-\d+/)[0]; + container.className = 'event-banner-container ' + colorClass + ' ' + hoverColorClass + ' hidden sm:block'; + } + + // All banners are hidden by default + banners.forEach(banner => banner.style.visibility = 'hidden'); - - Webinar - - - - Deploy FlowFuse on Industrial IoT with NCD.io - - - - - Learn more {% include "components/icons/chevron-right-sm.svg" %} - - + // Show the first banner + banners[0].style.visibility = 'visible'; + changeContainerColor(banners[0]); + + // If there is more than one banner, change the visible banner every 5 seconds + if (banners.length > 1) { + setInterval(function() { + // Hide the current banner + banners[currentBanner].style.visibility = 'hidden'; + + // Increment the current banner index + currentBanner = (currentBanner + 1) % banners.length; + + // Show the new banner + banners[currentBanner].style.visibility = 'visible'; + banners[currentBanner].style.animation = 'none'; // reset animation + // force reflow, triggering a new animation + void banners[currentBanner].offsetWidth; + banners[currentBanner].style.animation = 'slideDown 0.5s ease'; + + // Change the container color to match the new banner + setTimeout(function() { + changeContainerColor(banners[currentBanner]); + }, 500); // wait for the slideDown animation to finish + }, 7000); + } + }; + diff --git a/src/css/style.css b/src/css/style.css index 71f06302c3..29e9b6e3bf 100644 --- a/src/css/style.css +++ b/src/css/style.css @@ -203,6 +203,33 @@ dl.message-properties { @apply m-auto text-center sm:text-left p-8 max-w-md sm:max-w-screen-lg bg-indigo-50 border border-white rounded-lg mt-6; } +/* + Event banner +*/ +.event-banner-container { + position: relative; + height: 44px; + width: 100%; +} + +.event-banner { + position: absolute; + top: 0; + left: 0; + width: 100%; + visibility: hidden; + animation: slideDown 0.5s ease-in-out; +} + +.event-banner:first-child { + visibility: visible; +} + +@keyframes slideDown { + 0% { transform: translateY(-100%); } + 100% { transform: translateY(0); } +} + /* Blog */ From b1c7c08386ccdac37356f8be31dc703b53cfa283 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cyndira-flowforge=E2=80=9D?= <“yndira@flowforge.com”> Date: Tue, 14 May 2024 17:23:47 +0200 Subject: [PATCH 2/3] Update handbook --- src/handbook/customer/marketing/website.md | 29 +++++++++++++++++----- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/src/handbook/customer/marketing/website.md b/src/handbook/customer/marketing/website.md index ca34ae64f5..ae283ff6a2 100644 --- a/src/handbook/customer/marketing/website.md +++ b/src/handbook/customer/marketing/website.md @@ -12,16 +12,33 @@ navTitle: Marketing - Website ## Events Banner -To update the event banner that appears at the top of the Website, you will need two pieces of information: +The event banner at the top of the website can display more than one event or announcement. -- The title of the Webinar -- URL that the Webinar Registration is hosted at +To add or update an event, you'll need to modify the [following file](https://github.com/FlowFuse/website/blob/main/src/_data/events.yaml). The information should be formatted as follows for each banner: -Once you have those, you can update the [following file](https://github.com/FlowFuse/website/blob/main/src/_includes/components/events-banner.njk): +``` +- type: "Webinar" + title: "Deploy FlowFuse on Industrial IoT with NCD.io" + buttonText: "Learn more" + link: "/webinars/2024/deploy-flowfuse-on-industrial-iot-with-ncd-io/" +``` + +If there were more than one event, then duplicating that and updating the info will create the second banner for rotation. It would look like this: + +``` +- type: "Webinar" + title: "Deploy FlowFuse on Industrial IoT with NCD.io" + buttonText: "Learn more" + link: "/webinars/2024/deploy-flowfuse-on-industrial-iot-with-ncd-io/" +- type: "New Release" + title: "FlowFuse 2.4: making it easier to work with Snapshots, Blueprints & Devices " + buttonText: "See blog post" + link: "/blog/2024/05/flowfuse-2-4-release/" +``` -Update the `href=""` value of the `` tag to update the Event URL, and change the title inside the middle `` +If there is only one event, the banner will continuously display that event. If there are multiple events, the banner will rotate through them, displaying each one for a few seconds at a time. -You should also ensure that the banner is not disabled in [this file](https://github.com/FlowFuse/website/blob/main/src/_includes/layouts/base.njk). If it is, it would look like this: +Please also ensure that the banner is not disabled in [this file](https://github.com/FlowFuse/website/blob/main/src/_includes/layouts/base.njk). If it is, the code would look like this: `{% raw %} {# {% include "../components/events-banner.njk" %} #} {% endraw %}`. Please remove the comment symbols `{#` and `#}` to enable the banner. From 4c418d7570f693d9b511169a2b43ac9c4eb0f851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cyndira-flowforge=E2=80=9D?= <“yndira@flowforge.com”> Date: Wed, 15 May 2024 12:57:01 +0200 Subject: [PATCH 3/3] Add expiration functionality to event banners --- .eleventy.js | 3 +- .github/workflows/build.yml | 1 + src/_data/events.yaml | 3 +- src/_includes/components/events-banner.njk | 39 ++++++++++++++-------- src/_includes/layouts/base.njk | 2 +- src/handbook/customer/marketing/website.md | 13 +++++--- 6 files changed, 40 insertions(+), 21 deletions(-) diff --git a/.eleventy.js b/.eleventy.js index ee4005677c..a13b96f5c7 100644 --- a/.eleventy.js +++ b/.eleventy.js @@ -46,7 +46,8 @@ module.exports = function(eleventyConfig) { }); // Define a filter named 'isFutureDate' - eleventyConfig.addFilter('isFutureDate', (date) => { + eleventyConfig.addFilter('isFutureDate', (dateString) => { + const date = new Date(dateString); return date && date > new Date(); }); diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 53f8273a92..b3073a4e29 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -6,6 +6,7 @@ on: - main schedule: - cron: "30 9 * * *" + - cron: "5 16 * * 3,4" jobs: build_deploy: if: ${{ github.repository == 'FlowFuse/website' }} diff --git a/src/_data/events.yaml b/src/_data/events.yaml index fe7988d734..531cdb2588 100644 --- a/src/_data/events.yaml +++ b/src/_data/events.yaml @@ -1,4 +1,5 @@ - type: "Webinar" title: "Deploy FlowFuse on Industrial IoT with NCD.io" buttonText: "Learn more" - link: "/webinars/2024/deploy-flowfuse-on-industrial-iot-with-ncd-io/" \ No newline at end of file + link: "/webinars/2024/deploy-flowfuse-on-industrial-iot-with-ncd-io/" + expire: "2024-05-29T16:00:00Z" \ No newline at end of file diff --git a/src/_includes/components/events-banner.njk b/src/_includes/components/events-banner.njk index 21b1b675be..0829f60ffa 100644 --- a/src/_includes/components/events-banner.njk +++ b/src/_includes/components/events-banner.njk @@ -1,26 +1,39 @@ {% set colors = ["bg-indigo-700 hover:bg-indigo-600", "bg-indigo-800 hover:bg-indigo-700", "bg-indigo-900 hover:bg-indigo-800"] %} +{% set hasFutureEvents = false %} +{% for event in events %} + {% if event.expire | isFutureDate %} + {% set hasFutureEvents = true %} + {% endif %} +{% endfor %} + +{% if hasFutureEvents %}