diff --git a/inventory/routes/helpers.py b/inventory/routes/helpers.py
index 53bc469..356d169 100644
--- a/inventory/routes/helpers.py
+++ b/inventory/routes/helpers.py
@@ -1,7 +1,10 @@
+import base64
+import csv
import hashlib
+import io
import os
-from flask import url_for
+from flask import url_for, jsonify
from ..models import Inventory
@@ -82,3 +85,22 @@ def get_image_attachable_class_by_name(name: str):
if getattr(cls, '__tablename__', None) == name:
return cls
return None
+
+
+def make_csv(export_func, columns, rows):
+ output = io.StringIO()
+ writer = csv.writer(output)
+
+ writer.writerow(columns)
+
+ for row in rows:
+ writer.writerow([export_func(row, col) for col in columns])
+
+ csv_string = output.getvalue()
+ output.close()
+
+ return jsonify({
+ "success": True,
+ "csv": base64.b64encode(csv_string.encode()).decode(),
+ "count": len(rows)
+ })
\ No newline at end of file
diff --git a/inventory/routes/inventory.py b/inventory/routes/inventory.py
index 48855a1..0100936 100644
--- a/inventory/routes/inventory.py
+++ b/inventory/routes/inventory.py
@@ -7,7 +7,7 @@ from flask import request, render_template, url_for, jsonify
from sqlalchemy.inspection import inspect
from . import main
-from .helpers import FILTER_MAP, inventory_headers, worklog_headers
+from .helpers import FILTER_MAP, inventory_headers, worklog_headers, make_csv
from .. import db
from ..models import Inventory, User, Room, Item, RoomFunction, Brand, WorkLog
@@ -237,9 +237,6 @@ def get_inventory_csv():
return jsonify({"success": False, "error": "No IDs provided"}), 400
rows = eager_load_inventory_relationships(db.session.query(Inventory).filter(Inventory.id.in_(ids))).all()
-
- output = io.StringIO()
- writer = csv.writer(output)
columns = [
"id",
@@ -257,19 +254,7 @@ def get_inventory_csv():
"shared"
]
- writer.writerow(columns)
-
- for item in rows:
- writer.writerow([export_value(item, col) for col in columns])
-
- csv_string = output.getvalue()
- output.close()
-
- return jsonify({
- "success": True,
- "csv": base64.b64encode(csv_string.encode()).decode(),
- "count": len(rows)
- })
+ return make_csv(export_value, columns, rows)
@main.route("/inventory_available")
def inventory_available():
diff --git a/inventory/routes/user.py b/inventory/routes/user.py
index fb70c9a..91c2812 100644
--- a/inventory/routes/user.py
+++ b/inventory/routes/user.py
@@ -5,7 +5,7 @@ import io
from flask import render_template, request, jsonify
from . import main
-from .helpers import ACTIVE_STATUSES, user_headers, inventory_headers, worklog_headers
+from .helpers import ACTIVE_STATUSES, user_headers, inventory_headers, worklog_headers, make_csv
from .. import db
from ..utils.load import eager_load_user_relationships, eager_load_room_relationships, eager_load_inventory_relationships, eager_load_worklog_relationships
from ..models import User, Room, Inventory, WorkLog
@@ -148,9 +148,6 @@ def get_user_csv():
return jsonify({"success": False, "error": "No IDs provided"}), 400
rows = eager_load_user_relationships(db.session.query(User).filter(User.id.in_(ids))).all()
-
- output = io.StringIO()
- writer = csv.writer(output)
columns = [
"id",
@@ -162,16 +159,4 @@ def get_user_csv():
"supervisor"
]
- writer.writerow(columns)
-
- for user in rows:
- writer.writerow([export_value(user, col) for col in columns])
-
- csv_string = output.getvalue()
- output.close()
-
- return jsonify({
- "success": True,
- "csv": base64.b64encode(csv_string.encode()).decode(),
- "count": len(rows)
- })
\ No newline at end of file
+ return make_csv(export_value, columns, rows)
diff --git a/inventory/routes/worklog.py b/inventory/routes/worklog.py
index 3604cb6..57798d5 100644
--- a/inventory/routes/worklog.py
+++ b/inventory/routes/worklog.py
@@ -6,7 +6,7 @@ import io
from flask import request, render_template, jsonify
from . import main
-from .helpers import worklog_headers
+from .helpers import worklog_headers, make_csv
from .. import db
from ..models import WorkLog, User, Inventory, WorkNote
from ..utils.load import eager_load_worklog_relationships, eager_load_user_relationships, eager_load_inventory_relationships
@@ -172,9 +172,6 @@ def get_worklog_csv():
return jsonify({"success": False, "error": "No IDs provided"}), 400
rows = eager_load_worklog_relationships(db.session.query(WorkLog).filter(WorkLog.id.in_(ids))).all()
-
- output = io.StringIO()
- writer = csv.writer(output)
columns = [
"id",
@@ -188,16 +185,10 @@ def get_worklog_csv():
"latest_update"
]
- writer.writerow(columns)
+ return make_csv(export_value, columns, rows)
- for user in rows:
- writer.writerow([export_value(user, col) for col in columns])
-
- csv_string = output.getvalue()
- output.close()
-
- return jsonify({
- "success": True,
- "csv": base64.b64encode(csv_string.encode()).decode(),
- "count": len(rows)
- })
\ No newline at end of file
+ # return jsonify({
+ # "success": True,
+ # "csv": base64.b64encode(csv_string.encode()).decode(),
+ # "count": len(rows)
+ # })
\ No newline at end of file
diff --git a/inventory/static/js/csv.js b/inventory/static/js/csv.js
new file mode 100644
index 0000000..a484dc1
--- /dev/null
+++ b/inventory/static/js/csv.js
@@ -0,0 +1,35 @@
+async function export_csv(ids, csv_route) {
+ const payload = ids;
+
+ try {
+ const response = await fetch(`/api/${csv_route}/export`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "Accept": "application/json"
+ },
+ body: JSON.stringify(payload)
+ });
+
+ const result = await response.json();
+
+ if (result.success) {
+ const decodedCsv = atob(result.csv);
+ const blob = new Blob([decodedCsv], { type: "text/csv" });
+ const url = URL.createObjectURL(blob);
+
+ const link = document.createElement("a");
+ link.href = url;
+ link.download = `${csv_route}_export.csv`;
+ link.click();
+
+ console.log(url);
+
+ URL.revokeObjectURL(url);
+ } else {
+ renderToast({ message: `Export failed: ${result.error}`, type: 'danger' });
+ }
+ } catch (err) {
+ renderToast({ message: `Export failed: ${err}`, type: 'danger' });
+ }
+}
\ No newline at end of file
diff --git a/inventory/templates/layout.html b/inventory/templates/layout.html
index 4b9a81b..6b01a75 100644
--- a/inventory/templates/layout.html
+++ b/inventory/templates/layout.html
@@ -74,6 +74,7 @@
integrity="sha384-zqgMe4cx+N3TuuqXt4kWWDluM5g1CiRwqWBm3vpvY0GcDoXTwU8d17inavaLy3p3"
crossorigin="anonymous">
+