x x x
Only portrait mode is currently supported - please rotate your device.

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

HTML
<link rel="stylesheet" type="text/css" href="https://gsvlabs-confluence-files.s3-us-west-2.amazonaws.com/stylesheets/ESG/eventsDashboardStylesheet.css" />

<script type="text/javascript" src="https://gsvlabs-confluence-files.s3.us-west-2.amazonaws.com/staging-files/js/esgESG/eventsDashboard2021ScripttempEventsDashboard.js"></script>

<style>
.wiki-content .ev-banner-container .ev-banner-title .card-title {
	background-image: unset !important;
	-webkit-background-clip: unset !important;
	background-clip: unset !important;
	color: black !important;
}

.countryFilterContainer #country-placeholder {
    height: 45px;
    min-height: 45px;
    margin: 0px;
    text-align: left;
    width: calc(100% - 40px);
    justify-content: space-between;
    color: rgba(255, 255, 255, 0.69);
    padding: 0px 20px;
    cursor: text;
    position: relative;
    align-items: center;
    background: #1f1f1f;
    border: none;
}
.countryFilterContainer {
	justify-content: center !important;
}
.countryFilterContainer #country-clear-button {
    position: absolute;
    right: 0px;
}

.attendees {
	display: none;
}

@media screen and (max-width: 640px) {
.filtersContainer {
	justify-content: center;
}
}
</style>

...

Custom section
ContainerIDannouncementcontainer
Classev-banner-container


Show If
groupconfluence-administrators,judging-administrators


Custom section
CustomCSSheight:none; justify-content:flex-end;

Custom button
Typecustom-button
FontColor#000000
TextCreate / Edit Announcements
Url/display/EV/Events+Dashboard+Announcements



Custom section
CustomCSSflex-direction: column; width: 100%; max-width: 100%;
ContainerIDannouncements-wrapper
Classev-banner


ConfiForms PlainView
pageTitleEV:Events Dashboard Announcements
formNameeventsdashboardannouncements
sortcreated DESC
<div class="announcementcard fade">
	<div class="imgalign"> 
		<img class="announcement-image" src="/download/attachments/95587037/[entry.image.asAttachment]"></img>
 	</div>
	<div class="text-encompasser">
		<div class="change-slide-buttons-container">
			<div class="change-slide-button" onclick="plusSlides(-1)"><img src="/download/attachments/81517767/chev-left.png?api=v2" /></div>
			<div class="change-slide-button" onclick="plusSlides(1)"><img src="/download/attachments/81517767/chev-right.png?api=v2" /></div>
		</div>
		<div class="text-container ev-banner-title">
			<p class="card-title">[entry.title] </p>
		</div>
		<div class="text-container">
			<font class="card-subtitle">[entry.subtitle] </font>
		</div>
		<div class="text-container">
			<font class="card-description">[entry.description] </font>
		</div>
		<div class="announcement-links-container">
			<a class="buttonHref" href="[entry.cardLink]" rel="nofollow" target="_blank" onclick="handleEventCardClick(this);" data-cardtype="announcement" data-cardurl="[entry.cardLink]" data-entryid="[entry.id]" data-cardtitle="[entry.title]">
				[entry.cardButtonText]
			</a>
		</div>
	</div>
</div>


Carousel

...

HTML
<div class="ev-cards-outer-container">
	<div id="ev-cards-main-view">
Custom section


ev-cards-section-scrollable<h2
-scrollable" id="my-events-scrolly">
    <header class="
ev
event-cards-
section
container-
title
header">My Events</
h2>
header>
	<div class="event-cards-container event-cards-hr-scroll-layout" id="my-events-cards-container"></div>
</section>
<section class="event-group-section" id="upcoming-events-section">
	<header class="event-cards-container-header">Upcoming Events</header>
	<div class="scrolling-ev-cards-wrapper
">
		<div class="event-cards-container event-cards-hr-scroll-layout" id="upcoming-events-cards-container"></div>
	</div>
</section>
HTML
<section class="event-group-section 
CustomCSSdisplay:none;
ContainerIDmy-events-scrolly
Class
ev-cards-section
HTML
Custom section
Classscrolling-ev-cards-wrapper
ConfiForms CleanView
filterownedBy:[entry._user]
pageTitleCreate Event
formNamecreateEvent
sortstartDate asc
Custom section
ContainerIDupcoming-events-section
Classev-cards-section ev-cards-section-scrollable
HTML
<h2 class="ev-cards-section-title">Upcoming Events</h2>
Custom section
Class
ConfiForms CleanView
filterendDate:>=_now AND publish:true
pageTitleCreate Event
formNamecreateEvent
sortstartDate asc


custom-custom-section
ContainerIDmy-watchlist-container
Classev-cards-section ev-cards-section-scrollable


HTML
<h2 class="ev-cards-section-title">My Watchlist</h2>


Custom section
Classscrolling-ev-cards-wrapper


HTML
<div class="conf-macro output-block fullSite" data-hasbody="true" data-macro-name="confiform-cleanview"></div>




HTML
</div>
Custom section


<h2
">
	<header class="
ev
event-cards-
section
container-
title
header">Past Events</
h2>
header>
	<div class="scrolling-ev-cards-wrapper
HTML
<section class="event-group-section" id="
ContainerID
past-events-section
Classev-cards-section ev-cards-section-scrollable
HTML
Custom section
Class
ConfiForms CleanView
filterendDate:<[now] AND publish:true
pageTitleCreate Event
formNamecreateEvent
sortstartDate desc
Custom section
CustomCSSflex-direction: column;
ContainerIDall-events
Classev-cards-section
HTML
<h2 class="ev-cards-section-title" style="margin-bottom: 60px;">All Events</h2>
ConfiForms CleanView
filterpublish:true
pageTitleCreate Event
formNamecreateEvent
sortstartDate ASC
"> 
  		<div class="event-cards-container event-cards-hr-scroll-layout" id="past-events-cards-container"></div>
	</div>
</section>
<section class="event-group-section" id="all-events-section">
	<header class="event-cards-container-header">All Events</header>
	<div class="event-cards-container event-cards-grid-layout" id="all-events-cards-container"></div>
</section>



ContainerID
Show If
groupconfluence-administrators,judging-administrators
Custom section
CustomCSSflex-direction: column;


unpublished-events
Classev-cards-section
HTML
<h2
<section class="
ev
event-
cards
group-section
-title" style="margin-bottom: 60px;
" id="unpublished-events-section">
	<header class="event-cards-container-header">Unpublished Events</
h2>
ConfiForms CleanView
filterpublish:false
pageTitleCreate Event
formNamecreateEvent
sortstartDate ASC
HTML
	</div>
</div>
header>
	<div class="event-cards-container event-cards-grid-layout" id="unpublished-events-cards-container"></div>
</section>



HTML
	</div>
</div>


HTML
<style>
#unpublished-events .conf-
HTML
<style>
#unpublished-events .conf-macro.output-block[data-macro-name=confiform-cleanview] {
    padding: 0px 35px;
    display: grid;
    grid-template-columns: repeat(auto-fill, 280px);
    grid-gap: 20px;
    height: auto !important;
    justify-content: space-evenly;
}
</style>

...

HTML
 <script>

  const getMinutesUntilEventStart = (startDate) => {
    let nowDate = new Date();
    let eventStartDate = new Date(startDate);

    let diffMilliseconds = eventStartDate.getTime() - nowDate.getTime();
    let diffMinutes =  (diffMilliseconds / 60000);

    return diffMinutes;
  }

  const getMinutesUntilEventEnd = (endDate) => {
    let nowDate = new Date();
    let eventEndDate = new Date(endDate);

    let diffMilliseconds = eventEndDate.getTime() - nowDate.getTime();
    let diffMinutes =  (diffMilliseconds / 60000);

    return diffMinutes;
  }

  const showPastWatchIndicators = () => {
	let pastEvents = document.getElementById('scroll-section-3');
    let pastCards = Array.from(pastEvents.getElementsByClassName('eventcard'));

	for (let i = 0; i < pastCards.length; i++) {
      let currCard = pastCards[i];
	
	  // Check if event was offline 
	  if (currCard.dataset.offline == "true") {
		continue
	  }

      let liveEl = document.createElement("div");
      liveEl.classList.add('watch-indicator');
      liveEl.innerHTML = "<img class='watch-indicator-icon' src='/download/attachments/81517767/playicon.png?api=v2' /> RECORDED";
      currCard.insertAdjacentElement('afterbegin', liveEl);
    }

	let allEvents = document.getElementById('all-events');
	let allCards = Array.from(allEvents.getElementsByClassName('eventcard'));

	for (let i = 0; i < allCards.length; i++) {
	  let currCard = allCards[i];
      let currCardEnd = currCard.dataset.enddate;
      let minsTilEnd = getMinutesUntilEventEnd(currCardEnd);
	  if (minsTilEnd < 0) {
		// Check if event was offline 
	    if (currCard.dataset.offline == "true") {
		  continue
	    }
		let liveEl = document.createElement("div");
		liveEl.classList.add('watch-indicator');
		liveEl.innerHTML = "<img class='watch-indicator-icon' src='/download/attachments/81517767/playicon.png?api=v2' /> RECORDED";
		currCard.insertAdjacentElement('afterbegin', liveEl);
	  } else {
		// Live now or upcoming (show live indicator if minsTilStart <= 0)
		let currCardStart = currCard.dataset.startdate;
		let minsTilStart = getMinutesUntilEventStart(currCardStart);
		if (minsTilStart <= 0) {
			// Check if event is offline 
	    	if (currCard.dataset.offline == "true") {
		  		continue;
	    	}
			let liveEl = document.createElement("div");
        	liveEl.classList.add('live-circle')
		// Live now or upcoming (show live indicator if minsTilStart <= 0)
		let currCardStart = currCard.dataset.startdate;
		let minsTilStart = getMinutesUntilEventStart(currCardStart);
		if (minsTilStart <= 0) {
			// Check if event is offline 
	    	if (currCard.dataset.offline == "true") {
		  		continue;
	    	}
			let liveEl = document.createElement("div");
        	liveEl.classList.add('live-circle');
        	liveEl.innerText = "LIVE";
        	currCard.insertAdjacentElement('afterbegin', liveEl);
		}
	  }
	}
  }

  window.addEventListener('load', () => {
    let upcomingEvents = document.getElementById('upcoming-events-section');
    let upcomingCards = Array.from(upcomingEvents.getElementsByClassName('eventcard'));

    for (let i = 0; i < upcomingCards.length; i++) {
      let currCard = upcomingCards[i];
      let currCardStart = currCard.dataset.startdate;
      let minsTilStart = getMinutesUntilEventStart(currCardStart);

      if (minsTilStart <= 0) {
		// Check if event is offline 
	    if (currCard.dataset.offline == "true") {
		  	continue;
	    }
        let liveEl = document.createElement("div");
        liveEl.classList.add('live-circle');
        liveEl.innerText = "LIVE";
        currCard.insertAdjacentElement('afterbegin', liveEl);
      }  
    }
	
	//if (AJS.params.remoteUser == "alex@gsvlabs.com") {
		// showPastWatchIndicators();
	//}
  });
</script>
<style>
  .live-circle {
    font-size: 13px;
    padding: 3px 18px;
    text-transform: uppercase;
    font-weight: bold;
    background-color: #cc1f1f;
    color: white;
    position: absolute;
    z-index: 2;
    margin: 8px 8px;
    box-shadow: 1px 1px 5px #00000054;
  }
</style>

<style>
  .watch-indicator {
    font-size: 12px;
    padding: 3px 10px;
    text-transform: uppercase;
    font-weight: bold;
    background-color: #036bc4;
    color: white;
    position: absolute;
    z-index: 2;
    margin: 8px 8px;
    box-shadow: 1px 1px 5px #00000054;
	border-radius: 3px;
	display: flex;
	justify-content: center;
	align-items: center;
  }
  .watch-indicator-icon {
	display: block;
    width: 14px !important;
    height: 14px !important;
    margin-right: 6px;
    padding-bottom: 2px;
  }
</style>


HTML
<style>

.wiki-content #announcementcontainer .announcementcard a {
  color: black !important;
  border: none;
  border-bottom: 1px solid black !important;
  padding: 0;
  width: auto;
}

</style>


HTML
<script type="module">
const CREATE_EVENT_PAGE_ID = 107518480;
const CREATE_EVENT_FORM_NAME = "createEvent";

const EVENT_FILTER_SECTION_DATA = {
    myEvents: {
        selector: "my-events-cards-container",
        url: `/ajax/confiforms/rest/filter.action?pageId=${CREATE_EVENT_PAGE_ID}&f=${CREATE_EVENT_FORM_NAME}&ownedBy:${AJS.params.remoteUser}&sort=startDate ASC`,
    },
    upcomingEvents: {
        selector: "upcoming-events-cards-container",
        url: `/ajax/confiforms/rest/filter.action?pageId=${CREATE_EVENT_PAGE_ID}&f=${CREATE_EVENT_FORM_NAME}&q=publish:true&endDate:>=_now&sort=startDate ASC`,
    },
    pastEvents: {
        selector: "past-events-cards-container",
        url: `/ajax/confiforms/rest/filter.action?pageId=${CREATE_EVENT_PAGE_ID}&f=${CREATE_EVENT_FORM_NAME}&q=publish:true&endDate:<_now&sort=startDate DESC`,
    },
    allEvents: {
        selector: "all-events-cards-container",
        url: `/ajax/confiforms/rest/filter.action?pageId=${CREATE_EVENT_PAGE_ID}&f=${CREATE_EVENT_FORM_NAME}&q=publish:true&sort=startDate ASC`,
    },
    unpublishedEvents: {
        selector: "unpublished-events-cards-container",
        url: `/ajax/confiforms/rest/filter.action?pageId=${CREATE_EVENT_PAGE_ID}&f=${CREATE_EVENT_FORM_NAME}&q=publish:false&sort=startDate ASC`,
    },
};

import { format } from "https://cdn.skypack.dev/date-fns";
const getBulkEvents = async (requestURL) => {
    let result = await jQuery.ajax({
        url: requestURL,
        type: "get",
        dataType: "json",
    });
    return result.list?.entry;
};

const renderEventCards = async (eventFilterData) => {
    const eventsData = await getBulkEvents(eventFilterData.url);
    let allEventCardsHTML = "";
    if (!eventsData) {
        return;
    }
    for (const event of eventsData) {
        // Banner data from Confiforms is a Object string, convert or set default if no image is set.
        let bannerImageLink = "";
        let bannerImageURI = "";
        const {
            createdPage,
            offline,
            startDate,
            name,
            RSVPCount,
            bannerImage,
        } = event.fields;

        if (event.fields?.bannerImage) {
            const bannerImageData = JSON.parse(bannerImage)[0];
            bannerImageURI = /.png|.jpg/.test(bannerImageData.id)
                ? bannerImageData.id
                : bannerImageData.fileName;
            bannerImageLink = `/download/attachments/${createdPage}/${bannerImageURI}?api=v2`;
        } else {
            bannerImageLink =
                "https://passport-media.s3-us-west-1.amazonaws.com/ESG/events/ESG-default-dashboard.png";
        }
        const startDateObj = new Date(startDate);
        const formattedStartDate = format(startDateObj, "MMMM d");
        const formattedStartTime = format(startDateObj, "h:mm aaa");

        let eventCardHTML = `<div class="eventcard" onclick="handleEventCardClick(this);" data-cardtype="pastevents" data-cardurl="/pages/viewpage.action?pageId=${createdPage}" data-entryid="${event.id}" data-cardtitle="${name}" data-offline="${offline}" data-startdate="${formattedStartDate}">
            <a class="eventcardlink" href="/pages/viewpage.action?pageId=${createdPage}" id="${createdPage}">
                <div class="img-container">
                    <img src="${bannerImageLink}"></img>
                </div>
                <div class="text-container">
                    <div class="top">
                        <div class="dates"><p class="formattedDate">${formattedStartDate}</p></div>
                    </div>
                    <div class="bottom">
                        <div class="title">${name}</div>
                        <div class="dates"><p class="formattedDatetime">${formattedStartTime}</p></div>
                        <div class="attendees">${RSVPCount} Participants</div>
                    </div>
                </div>
            </a>
        </div>`;
        	liveEl.innerTextallEventCardsHTML += "LIVE"eventCardHTML;
    }
    	currCarddocument.insertAdjacentElement('afterbegin', liveEl);
		}
	  }
	}
  }

  window.addEventListener('load', (getElementById(eventFilterData.selector).innerHTML =
        allEventCardsHTML;
};

const renderScrollButtons = (scrollableSection, id) => {
    let upcomingEventscurrSection = document.getElementById('upcoming-events-section')scrollableSection;
    let upcomingCards = Array.from(upcomingEvents.getElementsByClassName('eventcard'));

currSection.id = `scroll-section-${id}`;
    forlet (letscrollContainer i = 0; i < upcomingCards.length; i++) {= document.createElement("div");
    scrollContainer.classList.add("scroll-buttons-container");
      let currCardscrollContainer.id = upcomingCards[i]`scroll-menu-${id}`;
      let currCardStartleftButton = currCard.dataset.startdate;`
    <div  let minsTilStart = getMinutesUntilEventStart(currCardStart);

class="scroll-button-container scroll-button-container-left">
        if (minsTilStart <= 0) {
		// Check if event is offline 
	    if (currCard.dataset.offline == "true") {
		  	continue;
	    }
    <div id="scroll-left-${id}" class="scroll-button">
        <img src="/download/attachments/${dashPageId}/chev-left.png?api=v2" />
        </div>
    </div>
    `;
    let liveElrightButton = document.createElement("div");`
    <div    liveEl.classList.add('live-circle');class="scroll-button-container scroll-button-container-right">
        liveEl.innerText<div id="scroll-right-${id}" class="LIVEscroll-button";>
        currCard.insertAdjacentElement('afterbegin', liveEl);<img src="/download/attachments/${dashPageId}/chev-right.png?api=v2" />
      }  </div>
    }
	
	//if (AJS.params.remoteUser == "alex@gsvlabs.com") {
		showPastWatchIndicators()
	//}
  });
</script>
<style>
  .live-circle {
    font-size: 13px</div>
    `;

    scrollContainer.innerHTML = leftButton + rightButton;
    padding: 3px 18px;
    text-transform: uppercase;currSection.insertAdjacentElement("beforeend", scrollContainer);

    currSection.addEventListener("scroll", () =>
    font-weight: bold;
    setTimeout(()  background-color: #cc1f1f;=> showOrHideScrollButtons(id), 200)
    color: white);
    position: absolute;leftButton.addEventListener("click", () =>
    z-index: 2;
    margin: 8px 8px    scrollLeft(`scroll-section-${id}`)
    );
    box-shadow: 1px 1px 5px #00000054;
  }
</style>

<style>
  .watch-indicator {rightButton.addEventListener("click", () =>
        scrollRight(`scroll-section-${id}`)
    font-size: 12px);

    padding: 3px 10px;updateScrollButtons();
};

Promise.all([
    text-transform: uppercase;renderEventCards(EVENT_FILTER_SECTION_DATA.myEvents),
    font-weight: bold;renderEventCards(EVENT_FILTER_SECTION_DATA.upcomingEvents),
    background-color: #036bc4;renderEventCards(EVENT_FILTER_SECTION_DATA.pastEvents),
    color: white;renderEventCards(EVENT_FILTER_SECTION_DATA.allEvents),
    position: absolute;
    z-index: 2renderEventCards(EVENT_FILTER_SECTION_DATA.unpublishedEvents),
]);

for (const group in EVENT_FILTER_SECTION_DATA) {
    console.log(group);
    margin: 8px 8pxrenderEventCards(EVENT_FILTER_SECTION_DATA[group]);
    box-shadow: 1px 1px 5px #00000054;
	border-radius: 3px;
	display: flex;
	justify-content: center;
	align-items: center;
  }
  .watch-indicator-icon {
	display: block;
    width: 14px !important;
    height: 14px !important;
    margin-right: 6px;
    padding-bottom: 2px;
  }
</style>
HTML
<style>

.wiki-content #announcementcontainer .announcementcard a {
  color: black !important;
  border: none;
  border-bottom: 1px solid black !important;
  padding: 0;
  width: auto;
}

</style>const sectionEle = document.getElementById(group.selector);
    renderScrollButtons(sectionEle, group.selector);
}

// window.onload(async (event) => {
//     console.log("BLAHBLAH");
//     console.log(event);
//     for (const group in EVENT_FILTER_SECTION_DATA) {
//         console.log(group);
//         await renderEventCards(EVENT_FILTER_SECTION_DATA[group]);
//         renderScrollButtons(group.selector);
//     }
//     renderScrollButtons();
// });
</script>

<link rel="stylesheet type="text/css" href="https://gsvlabs-confluence-files.s3.us-west-2.amazonaws.com/stylesheets/ESG/eventDashboard/updatedEventsDashboard.css" />