Skip to content

Commit

Permalink
resolve #40
Browse files Browse the repository at this point in the history
  • Loading branch information
CherrelleTucker committed Jan 17, 2024
1 parent 98fc965 commit 81f6b6a
Showing 1 changed file with 191 additions and 53 deletions.
244 changes: 191 additions & 53 deletions actionTrackerSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function onOpen() {
.addItem('Push actions from MO', 'pushActionsFromTabMO')
.addItem('Push actions from SEP', 'pushActionsFromTabSEP')
.addItem('Push actions from DevSeed', 'pushActionsFromTabDevSeed')
.addItem('Push actions from AssessmentHQ', 'pushActionsFromTabAssessmentHQ')
.addToUi();
}

Expand All @@ -86,7 +87,7 @@ var folderIds = {
MO: '1SRIUs7CUEdGUw0r1PI52e0OJpfXYN0z8',
SEP: '1Cw_sdH_IleGbtW1mVoWnJ0yqoyzr4Oe0',
DevSeed: '1Bvj1b1u2LGwjW5fStQaLRpZX5pmtjHSj',
AssessmentHQ: '1MEKTRBKum3UA4q97i9FJeBn49tMckbIn'// Assessment HQ Weekly Agenda/Notes
AssessmentHQ: '1V40h1Df4TMuuGzTMiLHxyBRPC-XJhQ10'// Testing Folder
};

///////////////////Pull///////////////////////////////////////////////
Expand Down Expand Up @@ -128,6 +129,35 @@ function pullActionsForFolderAssessmentHQ() {
}, 'pullActionsForFolderAssessmentHQ');
}

// Helper function to convert .docx file to Google Doc
function convertDocxToGoogleDoc(fileId) {
var file = DriveApp.getFileById(fileId);
var docxBlob = file.getBlob();

// Convert .docx to Google Doc
var options = {
method: "POST",
contentType: "application/json",
payload: JSON.stringify({
title: file.getName(),
mimeType: MimeType.GOOGLE_DOCS
}),
headers: {
Authorization: "Bearer " + ScriptApp.getOAuthToken()
},
muteHttpExceptions: true
};

var response = UrlFetchApp.fetch("https://www.googleapis.com/drive/v2/files/" + fileId + "/copy", options);
var googleDocId = JSON.parse(response.getContentText()).id;

// Delete the original .docx file
DriveApp.getFileById(fileId).setTrashed(true);

return googleDocId;
}


// Helper function to pull actions from a specific folder
function pullActionsForFolder(folderName) {
var folderId = folderIds[folderName];
Expand All @@ -142,47 +172,46 @@ function pullActionsForFolder(folderName) {
Logger.log('Step 2: Sheet populated with actions.');
}

// Pull helper function: Pull actions from documents
// Modified pullActionsFromDocuments function
function pullActionsFromDocuments(folderId) {
var folder = DriveApp.getFolderById(folderId);
var files = folder.getFilesByType(MimeType.GOOGLE_DOCS);
var files = folder.getFiles();

var allActions = [];

while (files.hasNext()) {
var file = files.next();
var docId = file.getId();
var docId;

if (file.getMimeType() === MimeType.GOOGLE_DOCS) {
docId = file.getId();
} else if (file.getMimeType() === MimeType.MICROSOFT_WORD || file.getName().toLowerCase().endsWith(".docx")) {
// Convert .docx file to Google Doc
docId = convertDocxToGoogleDoc(file.getId());
} else {
// Skip unsupported file types
continue;
}

var doc = DocumentApp.openById(docId);
var tables = doc.getBody().getTables();

for (var i = 0; i < tables.length; i++) {
var table = tables[i];
var numCols = table.getRow(0).getNumCells();

if (numCols !== 3) { // Skip tables that do not have 3 columns
continue;
}

var documentName = file.getName();
var documentLink = '=HYPERLINK("' + file.getUrl() + '", "' + documentName + '")';
var headers = getTableHeaders(table);

if (documentName.toLowerCase().indexOf('template') !== -1) { // Skip files with "Template" in the title
continue;
}

var tableData = tableTo2DArray(table);
var modifiedTableData = tableData.map(function (row) {
return [documentLink].concat(row);
});
// Check if the table has the required headers
if (hasRequiredHeaders(headers)) {
var documentName = file.getName();
var documentLink = '=HYPERLINK("' + file.getUrl() + '", "' + documentName + '")';

for (var j = 0; j < modifiedTableData.length; j++) {
var row = modifiedTableData[j];
var tableData = tableTo2DArray(table);
var filteredTableData = filterTableData(tableData, headers);

if (row.some(function (cell) { return cell === ''; })) { // Skip rows with empty cells
continue;
for (var j = 0; j < filteredTableData.length; j++) {
var row = [documentLink].concat(filteredTableData[j]);
allActions.push(row);
}

allActions.push(row);
}
}
}
Expand Down Expand Up @@ -279,36 +308,45 @@ pullActionsForAllFolders: success 11:02:56 AM pullActionsForAllFolders executi

////////////////// Push ////////////////////////////////////////////////////////

// Function to call the primary function on all named tabs
// Push function to call the primary function on all named tabs
function pushActionsFromAllTabs() {
logExecutionTime(function() {
updateStatusOnTab("MO");
updateStatusOnTab("SEP");
updateStatusOnTab("DevSeed");
updateStatusOnTab("AssessmentHQ");
}, 'pushActionsFromAllTabs');
}

// Function to call the primary function on the "MO" tab
// Push function to call the primary function on the "MO" tab
function pushActionsFromTabMO() {
logExecutionTime(function() {
updateStatusOnTab("MO");
}, 'pushActionsFromTabMO');
}

// Function to call the primary function on the "SEP" tab
// Push function to call the primary function on the "SEP" tab
function pushActionsFromTabSEP() {
logExecutionTime(function() {
updateStatusOnTab("SEP");
}, 'pushActionsFromTabSEP');
}

// Function to call the primary function on the "DevSeed" tab
// Push function to call the primary function on the "DevSeed" tab
function pushActionsFromTabDevSeed() {
logExecutionTime(function() {
updateStatusOnTab("DevSeed");
}, 'pushActionsFromTabDevSeed');
}

// Push function to call the primary function on the "AssessmentHQ" tab
function pushActionsFromTabAssessmentHQ() {
logExecutionTime(function() {
updateStatusOnTab("AssessmentHQ");
}, 'pushActionsFromTabAssessmentHQ');
}

// push function:
function updateStatusOnTab(tabName) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(tabName);
var range = sheet.getRange("A:G"); // Assuming the URL is in Column G
Expand All @@ -332,6 +370,7 @@ function updateStatusOnTab(tabName) {
}
}

//push function:
function updateStatusInSourceDoc(actionSource, status, task) {
// Column G now contains the extracted URL
var actionSourceUrl = actionSource; // No need for extractUrlFromHyperlink
Expand All @@ -341,51 +380,149 @@ function updateStatusInSourceDoc(actionSource, status, task) {
return;
}

try {
console.log("Attempting to open document with URL:", actionSourceUrl);
var sourceDoc = DocumentApp.openByUrl(actionSourceUrl);
} catch (error) {
console.error("Error opening document by URL:", error);
return;
}
try {
console.log("Attempting to open document with URL:", actionSourceUrl);
var sourceDoc = DocumentApp.openByUrl(actionSourceUrl);
} catch (error) {
console.error("Error opening document by URL:", error);
return;
}

// Get the body of the document
var body = sourceDoc.getBody();

// Find the table with the specified headings
var table = findTableByHeadings(body, ["Status", "Action"]);
var table = findTableByHeadings(body);

if (table) {
// Find the row with the matching task in the "Action" column
var rowIndex = findRowIndexByColumnValue(table, "Action", task);
// Log the table content for investigation
console.log("Table Content:", table.getText());

// Check the headers dynamically and find the row with the matching task
var columnIndex;
var expectedHeaders;
var lowerCaseHeaders = table.getRow(0).getText().toLowerCase().trim(); // Trim leading/trailing spaces
if (lowerCaseHeaders.includes("who")) {
// Headers are "Who What Status"
columnIndex = getColumnIndex(table, "What");
expectedHeaders = "Who What Status";
} else if (lowerCaseHeaders.includes("status") &&
lowerCaseHeaders.includes("owner") &&
lowerCaseHeaders.includes("action")) {
// Headers are "Status Owner Action"
columnIndex = getColumnIndex(table, "Action");
expectedHeaders = "Status Owner Action";
} else {
// Headers not recognized
console.error("Headers not recognized. Detected headers:", lowerCaseHeaders);
expectedHeaders = "Unknown";
}

// Find the row with the matching task in the specified column
var rowIndex = findRowIndexByColumnValue(table, table.getRow(0).getCell(columnIndex).getText(), task);

if (rowIndex !== -1) {
// Update the "Status" column with the status from the sheet
table.getCell(rowIndex, getColumnIndex(table, "Status")).setText(status);
console.log("Status Updated Successfully!");
} else {
console.error("Row with task not found in the table. Expected headers:", expectedHeaders);
}
} else {
console.error("Table not found with specified headings. Expected headers:", expectedHeaders);
}
}

// Push function: Get table headers
function getTableHeaders(table) {
var headers = [];
var row1 = table.getRow(0);

for (var col = 0; col < row1.getNumCells(); col++) {
headers.push(row1.getCell(col).getText().trim());
}

return headers;
}

// Helper function: Check if the table has the required headers
function hasRequiredHeaders(headers) {
// Check if the table has "Status" "Owner" "Action" or "Who" "What" "Status"
var hasStatus = headers.includes('Status') || headers.includes('Who'); // Column one heading
var hasOwner = headers.includes('Owner') || headers.includes('What'); // Column two heading
var hasAction = headers.includes('Action') || headers.includes('Status'); // Column three heading

return hasStatus && hasOwner && hasAction;
}

// Helper function: Filter table data based on headers
function filterTableData(tableData, headers) {
var filteredData = [];

for (var i = 0; i < tableData.length; i++) {
var rowData = tableData[i];
var filteredRow = ['', '', '']; // Initialize with empty values

for (var j = 0; j < headers.length; j++) {
var header = headers[j];
var columnIndex = headers.indexOf(header);

if (columnIndex !== -1) {
// Set values in corresponding columns based on header variations
switch (header.toLowerCase()) {
case 'status owner action':
filteredRow[0] = rowData[columnIndex];
filteredRow[1] = rowData[columnIndex + 1]; // Assuming 'Owner' is next
filteredRow[2] = rowData[columnIndex + 2]; // Assuming 'Action' is next
break;
case 'who what status':
filteredRow[0] = rowData[columnIndex + 2]; // Assuming 'Status' is last
filteredRow[1] = rowData[columnIndex]; // Assuming 'Who' is first
filteredRow[2] = rowData[columnIndex + 1]; // Assuming 'What' is in the middle
break;
// Add more cases for other header variations if needed
}
}
}

filteredData.push(filteredRow);
}
return filteredData;
}

function findTableByHeadings(body, headings) {
// Function to find a table in the document with specified headings
function findTableByHeadings(body) {
// Push function to find a table in the document with specified headings
var tables = body.getTables();


// Define possible header patterns
var headerPatterns = [
["who", "what", "status"],
["status", "owner", "action"]
];

for (var i = 0; i < tables.length; i++) {
var table = tables[i];
var headerRow = table.getRow(0);

// Check if the table has the specified headings
if (headings.every(function (heading) {
return headerRow.getText().indexOf(heading) !== -1;
})) {
return table;
var headerText = headerRow.getText().toLowerCase().replace(/\n/g, '');

// Check if the table headers match any of the predefined patterns
for (var j = 0; j < headerPatterns.length; j++) {
var pattern = headerPatterns[j];
var patternText = pattern.join("");
if (headerText.includes(patternText)) {
console.log("Table found with specified headings:", patternText);
return table;
}
}
}


console.error("Table not found with specified headings.");
console.log("Detected headings:", tables.map(table => table.getRow(0).getText().toLowerCase()));
return null;
}

function findRowIndexByColumnValue(table, columnName, value) {
// Function to find the row index in the table with a specific column value
// Push function to find the row index in the table with a specific column value
var columnIndex = getColumnIndex(table, columnName);

if (columnIndex !== -1) {
Expand All @@ -402,7 +539,7 @@ function findRowIndexByColumnValue(table, columnName, value) {
}

function getColumnIndex(table, columnName) {
// Function to get the index of a column in the table
// Push function to get the index of a column in the table
var headerRow = table.getRow(0);
var numCells = headerRow.getNumCells();

Expand All @@ -421,7 +558,8 @@ function getColumnIndex(table, columnName) {
'pushActionsFromTabMO': success 3:59:02 PM execution time: 0 minutes, 13.421 seconds
'pushActionsFromTabSEP': success 4:02:31 PM execution time: 0 minutes, 15.707 seconds
'pushActionsFromTabDevSeed': success 4:12:57 PM execution time: 0 minutes, 11.042 seconds
'pushActionsFromAllTabs': 4:16:43 PM execution time: 0 minutes, 31.064 seconds
'pushActionsFromAssessmentHQ': success 11:55:32 PM execution time: 0 minutes, 4.876 seconds
'pushActionsFromAllTabs': success 11:57:00 PM execution time: 0 minutes, 35.094 seconds
*/

///////////////Combine Open Actions///////////////////////////////////////////////
Expand Down

0 comments on commit 81f6b6a

Please sign in to comment.