diff --git a/.github/workflows/pull-requests.yml b/.github/workflows/pull-requests.yml
index 9749588..7986d58 100644
--- a/.github/workflows/pull-requests.yml
+++ b/.github/workflows/pull-requests.yml
@@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v4
- name: Use Node.js
- uses: actions/setup-node@v3
+ uses: actions/setup-node@v4
with:
node-version: '16'
diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml
index be35258..ea03092 100644
--- a/.github/workflows/static.yml
+++ b/.github/workflows/static.yml
@@ -24,13 +24,13 @@ jobs:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Pages
- uses: actions/configure-pages@v3
+ uses: actions/configure-pages@v4
- name: Build
run: make build && make pages
- name: Upload artifact
- uses: actions/upload-pages-artifact@v2
+ uses: actions/upload-pages-artifact@v3
with:
path: 'pages'
- name: Deploy to GitHub Pages
id: deployment
- uses: actions/deploy-pages@v2
+ uses: actions/deploy-pages@v4
diff --git a/assets/js/main.js b/assets/js/main.js
index 735bf52..4847fb5 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -1,178 +1,252 @@
-let isProcessingCSV = false;
-let isProcessingKML = false;
-
-const fetchMeetings = (query, callback, isCSV, isKML) => {
- const script = document.createElement("script");
- script.src = `${query}&callback=${callback.name}`;
- document.body.appendChild(script);
- isProcessingCSV = isCSV;
- isProcessingKML = isKML;
-};
-
-const handleMeetingsData = (meetings) => {
- if (isProcessingCSV) {
+class MeetingDataProcessor {
+ constructor() {
+ this.isProcessingCSV = false;
+ this.isProcessingKML = false;
+ }
+
+ // Load JSONP data
+ fetchMeetings(query, isCSV, isKML) {
+ MeetingDataProcessor.clearError();
+ MeetingDataProcessor.hideLinks();
+ return new Promise((resolve, reject) => {
+ const script = document.createElement("script");
+ const callbackName = `jsonpCallback_${Date.now()}`;
+
+ window[callbackName] = (data) => {
+ document.body.removeChild(script);
+ delete window[callbackName];
+
+ // check for empty array
+ if (Array.isArray(data) && data.length === 0) {
+ const errorMsg = "No data found";
+ MeetingDataProcessor.displayError(errorMsg);
+ reject(new Error(errorMsg));
+ } else {
+ this.handleMeetingsData(data, isCSV, isKML);
+ resolve(data);
+ }
+ };
+
+ script.src = `${query}&callback=${callbackName}`;
+ script.onerror = () => {
+ const errorMsg = "Error loading data";
+ MeetingDataProcessor.displayError(errorMsg);
+ reject(new Error(errorMsg));
+ };
+ document.body.appendChild(script);
+
+ this.isProcessingCSV = isCSV;
+ this.isProcessingKML = isKML;
+ });
+ }
+
+ static displayError(message) {
+ const errorContainer = document.getElementById("errorMessages");
+ if (errorContainer) {
+ errorContainer.textContent = message;
+ errorContainer.style.display = "block";
+ } else {
+ console.error("Error container not found in the document.");
+ }
+ }
+
+ static clearError() {
+ const errorContainer = document.getElementById("errorMessages");
+ if (errorContainer) {
+ errorContainer.style.display = "none";
+ errorContainer.textContent = "";
+ } else {
+ console.error("Error container not found in the document.");
+ }
+ }
+
+ // Handle data once it's fetched
+ handleMeetingsData(meetings, isCSV, isKML) {
+ if (isCSV) {
+ this.exportCSV(meetings);
+ }
+ if (isKML) {
+ this.exportKML(meetings);
+ }
+ }
+
+ // CSV export functionality
+ exportCSV(meetings) {
const csvContent = `data:text/csv;charset=utf-8,${encodeURIComponent(
- convertToCSV(meetings)
+ this.constructor.convertToCSV(meetings)
)}`;
const downloadLink = document.getElementById("downloadLink");
downloadLink.href = csvContent;
downloadLink.style.display = "block";
}
- if (isProcessingKML) {
+ // KML export functionality
+ exportKML(meetings) {
const kmlContent = `data:text/xml;charset=utf-8,${encodeURIComponent(
- convertToKML(meetings)
+ this.constructor.convertToKML(meetings)
)}`;
const kmlDownloadLink = document.getElementById("kmlDownloadLink");
kmlDownloadLink.href = kmlContent;
kmlDownloadLink.style.display = "block";
}
-};
-const convertToCSV = (data) => {
- const csvRows = [];
- const keys = Object.keys(data[0]);
-
- // header row
- csvRows.push(keys.join(","));
+ static hideLinks() {
+ const downloadLink = document.getElementById("downloadLink");
+ downloadLink.style.display = "none";
+ const kmlDownloadLink = document.getElementById("kmlDownloadLink");
+ kmlDownloadLink.style.display = "none";
+ }
- data.forEach((row) => {
- const values = keys.map((key) => {
- let value = row[key];
- if (typeof value === "string") {
- // Escape double quotes and wrap in double quotes if it contains a comma
- if (value.includes(",") || value.includes('"')) {
+ // Convert data to CSV
+ static convertToCSV(data) {
+ const csvRows = [];
+ const keys = Object.keys(data[0]);
+ csvRows.push(keys.join(","));
+
+ data.forEach((row) => {
+ const values = keys.map((key) => {
+ let value = row[key];
+ if (
+ typeof value === "string" &&
+ (value.includes(",") || value.includes('"'))
+ ) {
value = `"${value.replace(/"/g, '""')}"`;
}
- }
- return value;
+ return value;
+ });
+ csvRows.push(values.join(","));
});
- csvRows.push(values.join(","));
- });
-
- return csvRows.join("\n");
-};
+ return csvRows.join("\n");
+ }
-const convertToKML = (data) => {
- const kmlHeader = `
-
+ // Convert data to KML
+ static convertToKML(data) {
+ let kmlContent = `