added comp_systems and modular instances frontend
This commit is contained in:
82
src/Api/PluginLoader/PluginLoader.tsx
Normal file
82
src/Api/PluginLoader/PluginLoader.tsx
Normal file
@@ -0,0 +1,82 @@
|
||||
import React, { useRef, useEffect, useState, useMemo } from "react";
|
||||
import { useUserPreferencesStore } from "Stores/PreferencesStore";
|
||||
import type { TaskData } from "Types/Experiment/Experiment";
|
||||
|
||||
interface IframePluginProps {
|
||||
pluginUrl: string;
|
||||
mode: "list" | "editor";
|
||||
taskData: TaskData<any>;
|
||||
onUpdate?: (data: any) => void;
|
||||
}
|
||||
|
||||
export const IframePlugin: React.FC<IframePluginProps> = ({
|
||||
pluginUrl,
|
||||
mode,
|
||||
taskData,
|
||||
onUpdate,
|
||||
}) => {
|
||||
const iframeRef = useRef<HTMLIFrameElement>(null);
|
||||
const theme = useUserPreferencesStore();
|
||||
const [isIframeReady, setIsIframeReady] = useState(false);
|
||||
|
||||
// Memoize the iframe component to prevent recreation when taskData changes
|
||||
const memoizedIframe = useMemo(() => {
|
||||
const url = `${pluginUrl}?mode=${mode}`;
|
||||
return (
|
||||
<iframe
|
||||
ref={iframeRef}
|
||||
src={url}
|
||||
sandbox="allow-same-origin allow-scripts allow-popups allow-forms"
|
||||
style={{
|
||||
width: "100%",
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
flexGrow: 1,
|
||||
border: "none",
|
||||
}}
|
||||
title="Plugin"
|
||||
/>
|
||||
);
|
||||
}, [pluginUrl, mode]); // Only recreate when pluginUrl or mode changes
|
||||
|
||||
// Send data to iframe when taskData or theme changes, or when iframe becomes ready
|
||||
useEffect(() => {
|
||||
if (!isIframeReady || !iframeRef.current?.contentWindow) return;
|
||||
|
||||
const message = {
|
||||
type: "plugin-data",
|
||||
data: {
|
||||
taskData,
|
||||
theme: theme.theme,
|
||||
},
|
||||
};
|
||||
|
||||
iframeRef.current.contentWindow.postMessage(message, "*");
|
||||
}, [taskData, theme.theme, isIframeReady]);
|
||||
|
||||
// Listen for messages from iframe
|
||||
useEffect(() => {
|
||||
const handler = (event: MessageEvent) => {
|
||||
// Handle iframe ready signal
|
||||
if (event.data.type === "plugin-ready") {
|
||||
setIsIframeReady(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Handle plugin updates
|
||||
if (event.data.type === "plugin-update" && onUpdate) {
|
||||
onUpdate(event.data.data);
|
||||
}
|
||||
};
|
||||
|
||||
window.addEventListener("message", handler);
|
||||
return () => window.removeEventListener("message", handler);
|
||||
}, [onUpdate]);
|
||||
|
||||
// Reset ready state when URL changes (new plugin or mode)
|
||||
useEffect(() => {
|
||||
setIsIframeReady(false);
|
||||
}, [pluginUrl, mode]);
|
||||
|
||||
return memoizedIframe;
|
||||
};
|
||||
110
src/Api/QuantumBackend/MachineManagment.tsx
Normal file
110
src/Api/QuantumBackend/MachineManagment.tsx
Normal file
@@ -0,0 +1,110 @@
|
||||
import keycloak from "Api/Keycloak/Keycloak";
|
||||
import axios from "axios";
|
||||
import type {
|
||||
ComputationalSystemCreateRequest,
|
||||
ComputationalSystemCreateResponse,
|
||||
ComputationalSystemEditRequest,
|
||||
ComputationalSystemListResponse,
|
||||
SystemWithTeams,
|
||||
SystemStatusResponse,
|
||||
GiveSystemToTeamRequest,
|
||||
RemoveSystemFromTeamRequest,
|
||||
ComputationalSystemDeleteRequest,
|
||||
} from "Types/Machine/Machine";
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: `${import.meta.env.VITE_QUANTUM_BACKEND_URL}/machine`,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
});
|
||||
|
||||
// Add auth token to requests
|
||||
api.interceptors.request.use((config) => {
|
||||
const token = keycloak.token;
|
||||
if (token) {
|
||||
config.headers.Authorization = `Bearer ${token}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
// 1. Create or get computational system
|
||||
export const createOrGetComputationalSystem = async (
|
||||
data: ComputationalSystemCreateRequest,
|
||||
): Promise<ComputationalSystemCreateResponse> => {
|
||||
const response = await api.post<ComputationalSystemCreateResponse>("", data);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 2. Edit computational system (owner only)
|
||||
export const editComputationalSystem = async (
|
||||
data: ComputationalSystemEditRequest,
|
||||
): Promise<ComputationalSystemEditRequest> => {
|
||||
const response = await api.put<ComputationalSystemEditRequest>("", data);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 3. Get my systems (owned by current user)
|
||||
export const getMySystems = async ({
|
||||
page_num = 1,
|
||||
page_size = undefined,
|
||||
}): Promise<ComputationalSystemListResponse> => {
|
||||
const response = await api.get<ComputationalSystemListResponse>("", {
|
||||
params: { page_num, page_size },
|
||||
});
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 4. Get team systems (systems shared with a team)
|
||||
export const getTeamSystems = async (
|
||||
team_id: number,
|
||||
page_num: number = 1,
|
||||
page_size: number = 10,
|
||||
): Promise<ComputationalSystemListResponse> => {
|
||||
const response = await api.get<ComputationalSystemListResponse>("/team", {
|
||||
params: { team_id, page_num, page_size },
|
||||
});
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 5. Get computational system by ID
|
||||
export const getComputationalSystemById = async (
|
||||
system_id: number,
|
||||
): Promise<SystemWithTeams> => {
|
||||
const response = await api.get<SystemWithTeams>("/system", {
|
||||
params: { system_id },
|
||||
});
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 6. Get system status
|
||||
export const getSystemStatus = async (
|
||||
system_id: number,
|
||||
): Promise<SystemStatusResponse> => {
|
||||
const response = await api.get<SystemStatusResponse>("/status", {
|
||||
params: { system_id },
|
||||
});
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 7. Give system to team (share access)
|
||||
export const giveSystemToTeam = async (
|
||||
data: GiveSystemToTeamRequest,
|
||||
): Promise<GiveSystemToTeamRequest> => {
|
||||
const response = await api.put<GiveSystemToTeamRequest>("/team", data);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 8. Remove system from team (revoke access)
|
||||
export const removeSystemFromTeam = async (
|
||||
data: RemoveSystemFromTeamRequest,
|
||||
): Promise<{ message: string }> => {
|
||||
const response = await api.delete<{ message: string }>("/team", { data });
|
||||
return response.data;
|
||||
};
|
||||
|
||||
// 9. Delete computational system (owner only)
|
||||
export const deleteComputationalSystem = async (
|
||||
data: ComputationalSystemDeleteRequest,
|
||||
): Promise<{ message: string }> => {
|
||||
const response = await api.delete<{ message: string }>("", { data });
|
||||
return response.data;
|
||||
};
|
||||
@@ -1,48 +1,16 @@
|
||||
import keycloak from "Api/Keycloak/Keycloak";
|
||||
import axios from "axios";
|
||||
import type { Team, TeamMember } from "Types/Team/Team";
|
||||
|
||||
export interface TeamCreateRequest {
|
||||
name: string;
|
||||
description?: string | null;
|
||||
}
|
||||
|
||||
export interface TeamUpdateRequest {
|
||||
team_id: number;
|
||||
name: string;
|
||||
description?: string | null;
|
||||
}
|
||||
|
||||
export interface TeamCreateResponse {
|
||||
team_id: number;
|
||||
}
|
||||
|
||||
export interface TeamListRequest {
|
||||
page_num: number;
|
||||
page_size: number;
|
||||
}
|
||||
|
||||
export interface TeamDeleteRequest {
|
||||
team_id: number;
|
||||
}
|
||||
|
||||
export interface MemberAddRequest {
|
||||
team_id: number;
|
||||
user_id: string;
|
||||
permissions: string[];
|
||||
}
|
||||
|
||||
export interface MemberDeleteRequest {
|
||||
team_id: number;
|
||||
user_id: string;
|
||||
}
|
||||
|
||||
export interface TeamsListResponse {
|
||||
teams: Team[];
|
||||
cur_page: number;
|
||||
total_teams: number;
|
||||
page_size: number;
|
||||
}
|
||||
import type {
|
||||
Team,
|
||||
TeamMember,
|
||||
TeamCreateRequest,
|
||||
TeamCreateResponse,
|
||||
TeamUpdateRequest,
|
||||
TeamListRequest,
|
||||
TeamsListResponse,
|
||||
MemberAddRequest,
|
||||
MemberDeleteRequest,
|
||||
} from "Types/Team/Team";
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: `${import.meta.env.VITE_QUANTUM_BACKEND_URL}/team`,
|
||||
@@ -84,11 +52,13 @@ export const getTeams = async (
|
||||
return response.data;
|
||||
};
|
||||
|
||||
export const getShortTeamsList = async (): Promise<
|
||||
{ team_id: number; team_name: string }[]
|
||||
> => {
|
||||
const response =
|
||||
await api.get<{ team_id: number; team_name: string }[]>("short_list");
|
||||
export const getShortTeamsList = async (
|
||||
params: Partial<{ permission: string }>,
|
||||
): Promise<{ team_id: number; team_name: string }[]> => {
|
||||
const response = await api.get<{ team_id: number; team_name: string }[]>(
|
||||
"short_list",
|
||||
{ headers: {}, params },
|
||||
);
|
||||
return response.data;
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user