diff --git a/draw/api/drive_integration.py b/draw/api/drive_integration.py
index df2a585..da1f35b 100644
--- a/draw/api/drive_integration.py
+++ b/draw/api/drive_integration.py
@@ -58,6 +58,14 @@ def register_in_drive(diagram_name: str, team: str | None = None) -> str | None:
return drive_file.name
+@frappe.whitelist()
+def is_available() -> dict:
+ """Whether the Drive integration can be used (Drive installed + a team exists).
+ The editor calls this once to decide whether to show the "Add to Drive" action."""
+ installed = drive_installed()
+ return {"installed": installed, "ready": bool(installed and _default_team())}
+
+
@frappe.whitelist()
def add_to_drive(name: str) -> dict:
"""Whitelisted entry point for an "Add to Drive" action. Returns whether Drive
diff --git a/draw/draw/doctype/draw_diagram/test_draw_diagram.py b/draw/draw/doctype/draw_diagram/test_draw_diagram.py
index 0980978..8974456 100644
--- a/draw/draw/doctype/draw_diagram/test_draw_diagram.py
+++ b/draw/draw/doctype/draw_diagram/test_draw_diagram.py
@@ -136,6 +136,17 @@ def test_register_in_drive_when_available(self):
# Idempotent — a second call reuses the same File.
self.assertEqual(register_in_drive(doc.name, team=team), file_name)
+ def test_drive_is_available_reports_status(self):
+ # The editor calls is_available() to decide whether to show "Add to Drive".
+ # It must always return the two booleans without raising, Drive or not.
+ from draw.api.drive_integration import drive_installed, is_available
+
+ status = is_available()
+ self.assertEqual(status["installed"], drive_installed())
+ self.assertIn("ready", status)
+ if not drive_installed():
+ self.assertFalse(status["ready"])
+
def test_drive_registration_noops_without_team(self):
# Registration is a safe no-op when Drive isn't set up / not installed.
from draw.api import drive_integration
diff --git a/frontend/src/components/toolbar/DriveMenu.vue b/frontend/src/components/toolbar/DriveMenu.vue
new file mode 100644
index 0000000..42a5884
--- /dev/null
+++ b/frontend/src/components/toolbar/DriveMenu.vue
@@ -0,0 +1,52 @@
+
+
+
+