diff --git a/apps/console/src/pages/organizations/frameworks/FrameworkListView.tsx b/apps/console/src/pages/organizations/frameworks/FrameworkListView.tsx
index 56a70e4f2..a63ee336b 100644
--- a/apps/console/src/pages/organizations/frameworks/FrameworkListView.tsx
+++ b/apps/console/src/pages/organizations/frameworks/FrameworkListView.tsx
@@ -10,7 +10,7 @@ import { Link, useParams } from "react-router";
import type { FrameworkListViewQuery as FrameworkListViewQueryType } from "./__generated__/FrameworkListViewQuery.graphql";
import { PageTemplate } from "@/components/PageTemplate";
import { FrameworkListViewSkeleton } from "./FrameworkListPage";
-import { FrameworkImportDropdown } from "./ImportFrameworkDialog";
+import { FrameworkImportDropdown, FrameworkImportButton } from "./ImportFrameworkDialog";
const FrameworkListViewQuery = graphql`
query FrameworkListViewQuery($organizationId: ID!) {
@@ -44,7 +44,12 @@ function FrameworkListViewContent({
}
+ actions={
+
+
+
+
+ }
>
diff --git a/apps/console/src/pages/organizations/frameworks/ImportFrameworkDialog.tsx b/apps/console/src/pages/organizations/frameworks/ImportFrameworkDialog.tsx
index 7ff650b2f..6fcfff59c 100644
--- a/apps/console/src/pages/organizations/frameworks/ImportFrameworkDialog.tsx
+++ b/apps/console/src/pages/organizations/frameworks/ImportFrameworkDialog.tsx
@@ -10,7 +10,7 @@ import { useNavigate, useParams } from "react-router";
import { ConnectionHandler, graphql, useMutation } from "react-relay";
import { useToast } from "@/hooks/use-toast";
import { ImportFrameworkDialogImportFrameworkMutation } from "./__generated__/ImportFrameworkDialogImportFrameworkMutation.graphql";
-import { useState } from "react";
+import { useState, useRef } from "react";
const AVAILABLE_FRAMEWORKS = [
{ id: "ISO27001-2022", name: "ISO/IEC 27001:2022" },
@@ -158,3 +158,104 @@ export function FrameworkImportDropdown() {
);
}
+
+export function FrameworkImportButton() {
+ const { organizationId } = useParams();
+ const { toast } = useToast();
+ const fileInputRef = useRef(null);
+ const [isImporting, setIsImporting] = useState(false);
+ const [commit] = useMutation(
+ importFrameworkMutation
+ );
+
+ const handleFileChange = (e: React.ChangeEvent) => {
+ const file = e.target.files?.[0];
+ if (!file) return;
+
+ setIsImporting(true);
+
+ const connectionId = ConnectionHandler.getConnectionID(
+ organizationId!,
+ "FrameworkListView_frameworks"
+ );
+
+ commit({
+ variables: {
+ input: {
+ organizationId: organizationId!,
+ file: null,
+ },
+ connections: [connectionId],
+ },
+ uploadables: {
+ "input.file": file,
+ },
+ onCompleted(data, errors) {
+ setIsImporting(false);
+ if (errors) {
+ const error = errors[0];
+ let errorMessage = error.message || "Failed to import framework";
+
+ if (error?.message?.includes("already exists")) {
+ errorMessage = `A framework with this name already exists. Please choose a different name.`;
+ }
+
+ toast({
+ title: "Error",
+ description: errorMessage,
+ variant: "destructive",
+ });
+ return;
+ }
+
+ toast({
+ title: "Success",
+ description: "Framework imported successfully",
+ });
+ if (fileInputRef.current) {
+ fileInputRef.current.value = "";
+ }
+ },
+ onError(error) {
+ setIsImporting(false);
+ let errorMessage = error.message || "Failed to import framework";
+
+ if (error.message?.includes("already exists")) {
+ errorMessage = `A framework with this name already exists. Please choose a different name.`;
+ }
+
+ toast({
+ title: "Error",
+ description: errorMessage,
+ variant: "destructive",
+ });
+ },
+ });
+ };
+
+ return (
+ <>
+
+
+ >
+ );
+}