Network Error: Could not connect or retrieve data.
Check console for details.
`;
console.error('Error during file fetch:', error);
}
}
function renderFiles(files) {
files.forEach(file => {
fileTableBody.appendChild(createFileRow(file));
});
}
async function downloadFile(fileName) {
showMessage(`Preparing to download "${fileName}"...`, false);
try {
const bucket = catalyst.stratus.bucket(bucket_name);
const getObject = await bucket.getObject(fileName);
const getObjectResponse = await getObject.start();
const fileBlob = getObjectResponse.content;
if (fileBlob) {
const blobUrl = URL.createObjectURL(fileBlob);
const a = document.createElement('a');
a.href = blobUrl;
a.download = fileName;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(blobUrl);
hideMessage();
} else {
showMessage(`Failed to retrieve file content for "${fileName}".`, true);
setTimeout(hideMessage, 2000);
}
} catch (error) {
console.error('Error during file download:', error);
let errorMessage = `Error downloading "${fileName}". Please try again.`;
if (error && error.message && error.message.includes("404")) {
errorMessage = `File "${fileName}" not found in Stratus.`;
}
showMessage(errorMessage, true);
setTimeout(hideMessage, 3000);
}
}
async function deleteFile(rowId, fileName) {
showMessage(`Are you sure you want to delete "${fileName}"? This will remove it from storage and mark it as deleted.`, false);
messageCloseButton.textContent = 'Cancel';
const confirmDeleteButton = document.createElement('button');
confirmDeleteButton.textContent = 'Delete';
confirmDeleteButton.className = 'ml-4 px-4 py-2 bg-red-500 text-white rounded hover:bg-red-600';
const originalCloseHandler = messageCloseButton.onclick;
messageCloseButton.onclick = () => {
hideMessage();
messageCloseButton.textContent = 'Close';
messageCloseButton.onclick = originalCloseHandler;
confirmDeleteButton.remove();
};
messageCloseButton.parentNode.appendChild(confirmDeleteButton);
confirmDeleteButton.onclick = async () => {
hideMessage();
messageCloseButton.textContent = 'Close';
messageCloseButton.onclick = originalCloseHandler;
confirmDeleteButton.remove();
showMessage(`Processing deletion for "${fileName}"...`, false);
console.log(`Attempting to delete file from Stratus (Name: ${fileName}) and update DB (ROWID: ${rowId})`);
let dbUpdateSuccess = false;
let stratusDeleteSuccess = false;
try {
const bucket = catalyst.stratus.bucket(bucket_name);
await bucket.deleteObject(fileName);
stratusDeleteSuccess = true;
} catch (error) {
console.error('Error deleting file from Stratus:', error);
showMessage(`Failed to remove "${fileName}" from storage.`, true);
}
try {
const table = catalyst.table.tableId('FileVault');
const updateDetails = [
{
"ROWID": rowId,
"StratusUpload": "Deleted"
}
];
await table.updateRow(updateDetails);
dbUpdateSuccess = true;
} catch (error) {
console.error('Error updating Data Store row to "Deleted":', error);
if (stratusDeleteSuccess) {
showMessage(`File "${fileName}" removed from storage, but failed to mark as deleted in database.`, true);
} else {
showMessage(`Failed to mark "${fileName}" as deleted in database.`, true);
}
}
if (dbUpdateSuccess && stratusDeleteSuccess) {
showMessage(`"${fileName}" removed from storage!`, false);
fetchFiles();
setTimeout(hideMessage, 1500);
} else {
fetchFiles();
setTimeout(hideMessage, 3000);
}
};
}
fileTableBody.addEventListener('click', (event) => {
const targetButton = event.target.closest('.download-btn, .delete-btn');
if (!targetButton || targetButton.disabled) return;
const row = targetButton.closest('tr');
if (!row) return;
const rowId = row.dataset.rowId;
const fileName = row.dataset.fileName;
if (targetButton.classList.contains('download-btn')) {
downloadFile(fileName);
} else if (targetButton.classList.contains('delete-btn')) {
deleteFile(rowId, fileName);
}
});
await checkSignInStatus();
fetchFiles();
});
```
Next, update your `client-package.json` with the below code.
**client-package.json**
```json
{
"name": "WorkDriveSyncApp",
"version": "0.0.1",
"homepage" : "/__catalyst/auth/login",
"login_redirect" : "index.html"
}
```
The client directory is now configured.
Let us quickly go through the working of the functions and the client of the application:
* `index.html` contains the code for the front-end of the client. The
CSS is defined in `main.css`.
* `main.js`: The JavaScript function in the client
component that handles the various actions performed in the client through these
functions:
* **`checkSignInStatus()`:** Verifies whether the user is authenticated or not, if authenticated it allows user access to the app else displays an error and redirects the user to the login page.
* **`fetchFiles()`:** Fetches all file records from the Catalyst Data Store table.
* **`uploadFile (triggered via file input)`:** Handles file upload to Catalyst Stratus and updates metadata in the Data Store.
* **`downloadFile(fileName)`:** Downloads a file from the Stratus Bucket.
* **`deleteFile(rowId, fileName)`:** Deletes a file both from Stratus and the Data Store.
* **`logout()`**: Logs the user out of the application
* The **Event function** is triggered each time the event listener executes. This function performs the following actions:
* Downloads the file that was sent in as the event data by the event listener using a file stream
* Uploads the file and its metadata to WorkDrive through an API with the POST method. The OAuth credentials are passed to authorize this action.
* If the action is successful, the Work Drive sync status is set to "Completed". The record in the Data Store is updated with the WorkDrive file ID and the sync status.