Commit a91e1cac authored by Zac Wood's avatar Zac Wood

Added export calendar to PNG. Fixed some bugs on share page

parent 252c2ec9
Pipeline #3505 passed with stages
in 26 minutes and 24 seconds
v2.1.0
- Added "Save as PNG" feature for the calendar view
- Fixed bugs related to exporting/sharing a view-only schedule
...@@ -45,6 +45,14 @@ const addToSystemCalendar = () => { ...@@ -45,6 +45,14 @@ const addToSystemCalendar = () => {
window.open(`webcal://${window.location.hostname}/api/schedules?crns=${window.cart._courses.join(',')}`); window.open(`webcal://${window.location.hostname}/api/schedules?crns=${window.cart._courses.join(',')}`);
}; };
const saveImage = () => {
html2canvas(document.querySelector("#calendar")).then(canvas => {
canvas.toBlob(blob => {
saveAs(blob, 'GMU Schedule.png');
});
});
};
const initListeners = () => { const initListeners = () => {
const items = Array.from(document.querySelectorAll('.section-item')); const items = Array.from(document.querySelectorAll('.section-item'));
items.forEach(item => (item.onclick = () => remove(item))); items.forEach(item => (item.onclick = () => remove(item)));
...@@ -52,6 +60,7 @@ const initListeners = () => { ...@@ -52,6 +60,7 @@ const initListeners = () => {
document.getElementById('open-modal-btn').onclick = setUrlInModal; document.getElementById('open-modal-btn').onclick = setUrlInModal;
document.getElementById('download-ics').onclick = downloadIcs; document.getElementById('download-ics').onclick = downloadIcs;
document.getElementById('add-to-system').onclick = addToSystemCalendar; document.getElementById('add-to-system').onclick = addToSystemCalendar;
document.getElementById('save-image').onclick = saveImage;
document.getElementById('share-url').innerText = `${window.location.protocol}//${window.location.hostname}/schedule/view?crns=${window.cart._courses.join(',')}`; document.getElementById('share-url').innerText = `${window.location.protocol}//${window.location.hostname}/schedule/view?crns=${window.cart._courses.join(',')}`;
}; };
const params = new URLSearchParams(document.location.search);
const crns = params.get('crns');
document.addEventListener('DOMContentLoaded', () => { document.addEventListener('DOMContentLoaded', () => {
const eventsTemplate = document.querySelector('#events'); const eventsTemplate = document.querySelector('#events');
if (eventsTemplate) { if (eventsTemplate) {
...@@ -27,23 +30,32 @@ const renderEvents = (start, end, timezone, callback) => { ...@@ -27,23 +30,32 @@ const renderEvents = (start, end, timezone, callback) => {
* and sets the link in the modal to it. * and sets the link in the modal to it.
*/ */
const setUrlInModal = () => { const setUrlInModal = () => {
document.getElementById('calendar-link').innerText = `${window.location.protocol}//${window.location.hostname}/api/schedules?section_ids=${window.cart._courses.join(',')}`; document.getElementById('calendar-link').innerText = `${window.location.protocol}//${window.location.hostname}/api/schedules?crns=${crns}`;
}; };
const downloadIcs = async () => { const downloadIcs = async () => {
const response = await fetch(`${window.location.protocol}//${window.location.hostname}/api/schedules?section_ids=${window.cart._courses.join(',')}`); const response = await fetch(`${window.location.protocol}//${window.location.hostname}/api/schedules?crns=${crns}`);
const text = await response.text(); const text = await response.text();
const blob = new Blob([text], { type: 'text/calendar;charset=utf-8' }); const blob = new Blob([text], { type: 'text/calendar;charset=utf-8' });
saveAs(blob, 'GMU Schedule.ics'); saveAs(blob, 'GMU Schedule.ics');
}; };
const addToSystemCalendar = () => { const addToSystemCalendar = () => {
window.open(`webcal://${window.location.hostname}/api/schedules?section_ids=${window.cart._courses.join(',')}`); window.open(`webcal://${window.location.hostname}/api/schedules?crns=${crns}`);
};
const saveImage = () => {
html2canvas(document.querySelector("#calendar")).then(canvas => {
canvas.toBlob(blob => {
saveAs(blob, 'GMU Schedule.png');
});
});
}; };
const initListeners = () => { const initListeners = () => {
document.getElementById('open-modal-btn').onclick = setUrlInModal; document.getElementById('open-modal-btn').onclick = setUrlInModal;
document.getElementById('download-ics').onclick = downloadIcs; document.getElementById('download-ics').onclick = downloadIcs;
document.getElementById('add-to-system').onclick = addToSystemCalendar; document.getElementById('add-to-system').onclick = addToSystemCalendar;
document.getElementById('share-url').innerText = `${window.location.protocol}//${window.location.hostname}/schedule/view?section_ids=${window.cart._courses.join(',')}`; document.getElementById('share-url').innerText = `${window.location.protocol}//${window.location.hostname}/schedule/view?crns=${crns}`;
document.getElementById('save-image').onclick = saveImage;
}; };
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
padding: 16px; padding: 16px;
margin-bottom: 8px; margin-bottom: 8px;
margin-top: 8px; margin-top: 8px;
min-width: 800px; min-width: 1000px;
min-height: 800px;
} }
.section-item.selected { .section-item.selected {
......
<%= javascript_include_tag 'html2canvas.min' %>
<%= javascript_include_tag 'schedules' %> <%= javascript_include_tag 'schedules' %>
<%= stylesheet_link_tag 'schedules' %> <%= stylesheet_link_tag 'schedules' %>
...@@ -12,7 +14,10 @@ ...@@ -12,7 +14,10 @@
<button id="open-modal-btn" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exportModal"> <button id="open-modal-btn" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exportModal">
Export Schedule Export Schedule
</button> </button>
<button id="save-image" class="btn btn-secondary">Save as PNG</button>
<div id="calendar"></div> <div id="calendar"></div>
<h3>Quick add</h3> <h3>Quick add</h3>
<p>Populate your calendar quickly by entering a comma separated list of CRNs.</p> <p>Populate your calendar quickly by entering a comma separated list of CRNs.</p>
<form action="/sessions/add_bulk" class="form"> <form action="/sessions/add_bulk" class="form">
......
<%= javascript_include_tag 'html2canvas.min' %>
<%= javascript_include_tag 'schedules_view' %> <%= javascript_include_tag 'schedules_view' %>
<%= stylesheet_link_tag 'schedules' %> <%= stylesheet_link_tag 'schedules' %>
...@@ -12,6 +14,8 @@ ...@@ -12,6 +14,8 @@
<button id="open-modal-btn" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exportModal"> <button id="open-modal-btn" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exportModal">
Export Schedule Export Schedule
</button> </button>
<button id="save-image" class="btn btn-secondary" onclick="saveImage()">Save as PNG</button>
<div id="calendar"></div> <div id="calendar"></div>
<template id="events" data-events="<%= @events.to_json %>"></template> <template id="events" data-events="<%= @events.to_json %>"></template>
......
...@@ -31,4 +31,5 @@ Rails.application.config.assets.precompile += %w( ...@@ -31,4 +31,5 @@ Rails.application.config.assets.precompile += %w(
moment.min.js moment.min.js
fullcalendar.min.js fullcalendar.min.js
fullcalendar.min.css fullcalendar.min.css
html2canvas.min.js
) )
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment