diff --git a/server/src/api/record.ts b/server/src/api/record.ts index b8f1f2bc..3f1dcd50 100644 --- a/server/src/api/record.ts +++ b/server/src/api/record.ts @@ -114,7 +114,6 @@ router.get("/robots/:id", requireAPIKey, async (req: Request, res: Response) => } }); -// TODO: Format runs to send more data formatted router.get("/robots/:id/runs", requireAPIKey, async (req: Request, res: Response) => { try { const runs = await Run.findAll({ diff --git a/server/src/models/Robot.ts b/server/src/models/Robot.ts index a48b9af1..d2dbca67 100644 --- a/server/src/models/Robot.ts +++ b/server/src/models/Robot.ts @@ -1,6 +1,8 @@ import { Model, DataTypes, Optional } from 'sequelize'; import sequelize from '../storage/db'; import { WorkflowFile, Where, What, WhereWhatPair } from 'maxun-core'; +import User from './User'; // Import User model +import Run from './Run'; interface RobotMeta { name: string; @@ -17,6 +19,7 @@ interface RobotWorkflow { interface RobotAttributes { id: string; + userId?: number; recording_meta: RobotMeta; recording: RobotWorkflow; google_sheet_email?: string | null; @@ -30,6 +33,7 @@ interface RobotCreationAttributes extends Optional { } class Robot extends Model implements RobotAttributes { public id!: string; + public userId!: number; public recording_meta!: RobotMeta; public recording!: RobotWorkflow; public google_sheet_email!: string | null; @@ -46,6 +50,10 @@ Robot.init( defaultValue: DataTypes.UUIDV4, primaryKey: true, }, + userId: { + type: DataTypes.INTEGER, + allowNull: false, + }, recording_meta: { type: DataTypes.JSONB, allowNull: false, @@ -82,4 +90,9 @@ Robot.init( } ); +// Robot.hasMany(Run, { +// foreignKey: 'robotId', +// as: 'runs', // Alias for the relation +// }); + export default Robot; \ No newline at end of file diff --git a/server/src/models/User.ts b/server/src/models/User.ts index 5a3d552c..2bb465d2 100644 --- a/server/src/models/User.ts +++ b/server/src/models/User.ts @@ -1,5 +1,6 @@ import { DataTypes, Model, Optional } from 'sequelize'; import sequelize from '../storage/db'; +import Robot from './Robot'; interface UserAttributes { id: number; @@ -79,4 +80,9 @@ User.init( } ); +// User.hasMany(Robot, { +// foreignKey: 'userId', +// as: 'robots', // Alias for the relation +// }); + export default User; diff --git a/server/src/workflow-management/classes/Generator.ts b/server/src/workflow-management/classes/Generator.ts index 0516703b..6d29b5fd 100644 --- a/server/src/workflow-management/classes/Generator.ts +++ b/server/src/workflow-management/classes/Generator.ts @@ -126,10 +126,12 @@ export class WorkflowGenerator { * @private */ private registerEventHandlers = (socket: Socket) => { - socket.on('save', async (fileName: string) => { - logger.log('debug', `Saving workflow ${fileName}`); - await this.saveNewWorkflow(fileName) - }); + socket.on('save', (data) => { + console.log('Received data:', data); + const { fileName, userId } = data; + logger.log('debug', `Saving workflow ${fileName} for user ID ${userId}`); + this.saveNewWorkflow(fileName, userId); + }); socket.on('new-recording', () => this.workflowRecord = { workflow: [], }); @@ -477,7 +479,7 @@ export class WorkflowGenerator { * @param fileName The name of the file. * @returns {Promise} */ - public saveNewWorkflow = async (fileName: string) => { + public saveNewWorkflow = async (fileName: string, userId: number) => { const recording = this.optimizeWorkflow(this.workflowRecord); try { this.recordingMeta = { @@ -489,6 +491,7 @@ export class WorkflowGenerator { params: this.getParams() || [], } const robot = await Robot.create({ + userId, recording_meta: this.recordingMeta, recording: recording, }); @@ -497,7 +500,7 @@ export class WorkflowGenerator { } catch (e) { const { message } = e as Error; - logger.log('warn', `Cannot save the file to the local file system`) + logger.log('warn', `Cannot save the file to the local file system ${e}`) } this.socket.emit('fileSaved'); } diff --git a/src/components/molecules/SaveRecording.tsx b/src/components/molecules/SaveRecording.tsx index 3e82048e..e9efe532 100644 --- a/src/components/molecules/SaveRecording.tsx +++ b/src/components/molecules/SaveRecording.tsx @@ -1,8 +1,9 @@ -import React, { useCallback, useEffect, useState } from 'react'; +import React, { useCallback, useEffect, useState, useContext } from 'react'; import { IconButton, Button, Box, LinearProgress, Tooltip } from "@mui/material"; import { GenericModal } from "../atoms/GenericModal"; import { stopRecording } from "../../api/recording"; import { useGlobalInfoStore } from "../../context/globalInfo"; +import { AuthContext } from '../../context/auth'; import { useSocketStore } from "../../context/socket"; import { TextField, Typography } from "@mui/material"; import { WarningText } from "../atoms/texts"; @@ -24,6 +25,8 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { const { browserId, setBrowserId, notify, recordings } = useGlobalInfoStore(); const { socket } = useSocketStore(); + const { state, dispatch } = useContext(AuthContext); + const { user } = state; const navigate = useNavigate(); const handleChangeOfTitle = (event: React.ChangeEvent) => { @@ -56,9 +59,15 @@ export const SaveRecording = ({ fileName }: SaveRecordingProps) => { // notifies backed to save the recording in progress, // releases resources and changes the view for main page by clearing the global browserId const saveRecording = async () => { - socket?.emit('save', recordingName) - setWaitingForSave(true); - } + if (user) { + const payload = { fileName: recordingName, userId: user.id }; + socket?.emit('save', payload); + setWaitingForSave(true); + console.log(`Saving the recording as ${recordingName} for userId ${user.id}`); + } else { + console.error('User not logged in. Cannot save recording.'); + } + }; useEffect(() => { socket?.on('fileSaved', exitRecording);