102 lines
No EOL
3 KiB
Text
102 lines
No EOL
3 KiB
Text
/**
|
|
* MASTER API GATEWAY
|
|
*/
|
|
function doGet() {
|
|
try {
|
|
const data = {
|
|
lastUpdated: new Date().toLocaleString(),
|
|
projects: getProjectData(),
|
|
announcements: getAnnouncements(),
|
|
calendar: getCalendarData()
|
|
};
|
|
return ContentService.createTextOutput(JSON.stringify(data))
|
|
.setMimeType(ContentService.MimeType.JSON);
|
|
} catch (e) {
|
|
return ContentService.createTextOutput(JSON.stringify({ error: e.toString() }))
|
|
.setMimeType(ContentService.MimeType.JSON);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* PAGE 1 & 2: Project Retrieval & Filtering
|
|
*/
|
|
function getProjectData() {
|
|
const ss = SpreadsheetApp.getActiveSpreadsheet();
|
|
const sheets = ss.getSheets();
|
|
const active = [];
|
|
const completed = [];
|
|
const seen = new Set();
|
|
|
|
sheets.forEach(sheet => {
|
|
const sheetName = sheet.getName();
|
|
if (["Announcements", "Calendar"].includes(sheetName)) return;
|
|
|
|
const rows = sheet.getDataRange().getValues();
|
|
if (rows.length < 2) return;
|
|
|
|
rows.slice(1).forEach(row => {
|
|
const name = row[2]; // Column C
|
|
if (!name || seen.has(name)) return;
|
|
seen.add(name);
|
|
|
|
const completionVal = row[6]; // Column G
|
|
let progress = 0;
|
|
let isDone = false;
|
|
|
|
// Logic: Date object = Done, Number (0-99) = Progress, 100 = Done
|
|
if (completionVal instanceof Date) {
|
|
isDone = true;
|
|
} else if (typeof completionVal === 'number') {
|
|
progress = Math.min(Math.max(completionVal, 0), 100);
|
|
if (progress >= 100) isDone = true;
|
|
}
|
|
|
|
const p = {
|
|
name: name,
|
|
type: row[1] || "General",
|
|
owner: row[4] || "Unassigned",
|
|
due: row[5] instanceof Date ? Utilities.formatDate(row[5], Session.getScriptTimeZone(), "MMM dd") : (row[5] || "TBD"),
|
|
progress: progress,
|
|
isOverdue: (row[5] instanceof Date && row[5] < new Date() && !isDone)
|
|
};
|
|
|
|
if (isDone) completed.push(p);
|
|
else active.push(p);
|
|
});
|
|
});
|
|
|
|
return { active: active, completedCount: completed.length };
|
|
}
|
|
|
|
/**
|
|
* PAGE 3: Announcements
|
|
*/
|
|
function getAnnouncements() {
|
|
try {
|
|
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Announcements");
|
|
if (!sheet) return [];
|
|
const rows = sheet.getDataRange().getValues().slice(1);
|
|
return rows.map(r => ({
|
|
date: r[0] instanceof Date ? Utilities.formatDate(r[0], Session.getScriptTimeZone(), "MMM dd") : r[0],
|
|
title: r[1] || "",
|
|
content: r[2] || ""
|
|
})).filter(a => a.title !== "");
|
|
} catch(e) { return []; }
|
|
}
|
|
|
|
/**
|
|
* PAGE 4: Google Calendar
|
|
*/
|
|
function getCalendarData() {
|
|
try {
|
|
const now = new Date();
|
|
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
|
const events = CalendarApp.getDefaultCalendar().getEvents(now, endOfMonth);
|
|
|
|
return events.map(e => ({
|
|
title: e.getTitle(),
|
|
start: Utilities.formatDate(e.getStartTime(), Session.getScriptTimeZone(), "MMM dd"),
|
|
isBirthday: e.getTitle().toLowerCase().includes("birthday")
|
|
})).slice(0, 6);
|
|
} catch(e) { return []; }
|
|
} |