From 4331f88c9ad9ec557da6bd47209d463aa28f9a04 Mon Sep 17 00:00:00 2001 From: sabarinathan Date: Thu, 29 May 2025 15:39:12 +0530 Subject: [PATCH] builder,vizualization socket functionality completed --- src/shared/services/builder/lineService.ts | 34 +- src/shared/services/builder/wallService.ts | 261 +++++++------- src/shared/services/builder/zoneService.ts | 32 +- .../builderController/asset-Controller.ts | 216 +++++++++++ .../builderController/camera-Controller.ts | 73 ++++ .../environment-Controller.ts | 72 ++++ .../builderController/line-Controller.ts | 341 ++++++++++++++++++ .../builderController/wall-Controller.ts | 147 ++++++++ .../builderController/zone-Controller.ts | 140 +++++++ .../projectController.ts | 0 .../3dWidget-Controller.ts | 186 ++++++++++ .../floatWidget-Controller.ts | 187 ++++++++++ .../panel-Controller.ts | 247 +++++++++++++ .../template-Controller.ts | 189 ++++++++++ .../widget-Controller.ts | 128 +++++++ src/socket-server/manager/manager.ts | 91 +++-- src/socket-server/socket/events.ts | 167 ++++++--- src/socket-server/socket/socketManager.ts | 2 +- 18 files changed, 2317 insertions(+), 196 deletions(-) create mode 100644 src/socket-server/controllers/builderController/asset-Controller.ts create mode 100644 src/socket-server/controllers/builderController/camera-Controller.ts create mode 100644 src/socket-server/controllers/builderController/environment-Controller.ts create mode 100644 src/socket-server/controllers/builderController/line-Controller.ts create mode 100644 src/socket-server/controllers/builderController/wall-Controller.ts create mode 100644 src/socket-server/controllers/builderController/zone-Controller.ts rename src/socket-server/controllers/{project => projectController}/projectController.ts (100%) create mode 100644 src/socket-server/controllers/vizualizationController/3dWidget-Controller.ts create mode 100644 src/socket-server/controllers/vizualizationController/floatWidget-Controller.ts create mode 100644 src/socket-server/controllers/vizualizationController/panel-Controller.ts create mode 100644 src/socket-server/controllers/vizualizationController/template-Controller.ts create mode 100644 src/socket-server/controllers/vizualizationController/widget-Controller.ts diff --git a/src/shared/services/builder/lineService.ts b/src/shared/services/builder/lineService.ts index 4894d28..bf4836b 100644 --- a/src/shared/services/builder/lineService.ts +++ b/src/shared/services/builder/lineService.ts @@ -1,5 +1,5 @@ import lineModel from "../../V1Models/Builder/linesModel.ts"; -import { existingUser } from "../helpers/v1projecthelperFns.ts"; +import { existingProjectById, existingUser } from "../helpers/v1projecthelperFns.ts"; interface ILineItems { organization: string; layer: number; @@ -45,6 +45,12 @@ export const CreateLineItems = async ( const { organization, line, type, layer, projectId, userId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const newLine = await lineModel(organization).create({ layer, line, @@ -71,7 +77,13 @@ export const UpdateLineItems = async ( const { organization, projectId, uuid, position, userId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; - const updateResult = await lineModel(organization).updateMany( + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const updateResult= await lineModel(organization).updateMany( { "line.uuid": uuid, projectId: projectId }, { $set: { "line.$.position": position } } ); @@ -99,6 +111,12 @@ export const DeleteLineItems = async ( const { organization, projectId, line, userId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const inputUuids = line.map((item: any) => item.uuid); const findValue = await lineModel(organization).findOneAndDelete( @@ -137,6 +155,12 @@ export const DeleteLayer = async ( const { organization, projectId, layer, userId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const findValue = await lineModel(organization).find({ layer: layer, projectId: projectId, @@ -208,6 +232,12 @@ export const DeleteLinePoints = async ( const { organization, projectId, uuid, userId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const findValue = await lineModel(organization).deleteMany( { projectId: projectId, isArchive: false }, { diff --git a/src/shared/services/builder/wallService.ts b/src/shared/services/builder/wallService.ts index 3ec6824..7cd3465 100644 --- a/src/shared/services/builder/wallService.ts +++ b/src/shared/services/builder/wallService.ts @@ -1,5 +1,5 @@ import wallItemModel from "../../../shared/model/builder/assets/wallitems-Model.ts"; -import { existingUser } from "../helpers/v1projecthelperFns.ts"; +import { existingProjectById, existingUser } from "../helpers/v1projecthelperFns.ts"; interface IWallSetupData { modelUuid: string; modelName: string; @@ -29,138 +29,153 @@ interface IWallItemResult { data?: Object; status: string; } -export class WallItems { - static async setWallItems(data: IWallSetupData): Promise { - try { - const { - userId, - modelUuid, - modelName, - position, - type, - csgposition, - csgscale, - quaternion, - scale, - projectId, - organization, - } = data; - const UserExists = await existingUser(userId, organization); - if (!UserExists) return { status: "User not found" }; - const findvalue = await wallItemModel(organization).findOne({ - modelUuid: modelUuid, - isArchive: false, - }); +export const setWallItems = async (data: IWallSetupData): Promise => { + try { + const { + userId, + modelUuid, + modelName, + position, + type, + csgposition, + csgscale, + quaternion, + scale, + projectId, + organization, + } = data; + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const findvalue = await wallItemModel(organization).findOne({ + modelUuid: modelUuid, + }); - if (findvalue) { - const updatevalue = await wallItemModel(organization).findOneAndUpdate( - { modelUuid: modelUuid, projectId: projectId, isArchive: false }, - { - modelName, - position, - type, - csgposition, - csgscale, - quaternion, - scale, - }, - { new: true } - ); - return { - status: "Updated successfully", - data: updatevalue, - }; - } else { - const newValue = await wallItemModel(organization).create({ - modelUuid, + if (findvalue) { + const updatevalue = await wallItemModel(organization).findOneAndUpdate( + { modelUuid: modelUuid, projectId: projectId }, + { modelName, position, type, - projectId, csgposition, csgscale, quaternion, scale, - }); - return { - status: "wall Item created successfully", - data: newValue, - }; - } - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } - } - } - static async getWallItems(data: IWallGet) { - try { - const { organization, userId, projectId } = data; - const UserExists = await existingUser(userId, organization); - if (!UserExists) return { status: "User not found" }; - const findValue = await wallItemModel(organization).find({ - projectId: projectId, - isArchive: false, + }, + { new: true } // Return the updated document + ); + return { + status: "Updated successfully", + data: updatevalue, + }; + // res.status(201).json(updatevalue); + } else { + const newValue = await wallItemModel(organization).create({ + modelUuid, + modelName, + position, + type, + projectId, + csgposition, + csgscale, + quaternion, + scale, }); - if (!findValue) { - return { - status: "wallitems not found", - }; - } else { - return { - status: "Success", - data: findValue, - }; - } - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } + return { + status: "wall Item created successfully", + data: newValue, + }; + // res.status(201).json(newValue); } - } - static async deleteWallItems(data: IWallDelete): Promise { - try { - const { modelUuid, modelName, organization, userId, projectId } = data; - const UserExists = await existingUser(userId, organization); - if (!UserExists) return { status: "User not found" }; - const findValue = await wallItemModel(organization).findOneAndDelete({ - modelUuid: modelUuid, - modelName: modelName, - projectId: projectId, - isArchive: false, - }); - if (!findValue) { - return { - status: "model not found", - }; - } else { - return { - status: "Success", - data: findValue, - }; - } - } catch (error: unknown) { - if (error instanceof Error) { - return { - status: error.message, - }; - } else { - return { - status: "An unexpected error occurred", - }; - } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const getWallItems = async (data: IWallGet) => { + try { + const { organization, userId, projectId } = data; + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const findValue = await wallItemModel(organization).find({ + projectId: projectId, + }); + if (!findValue) { + return { + status: "wallitems not found", + }; + } else { + return { + status: "Success", + data: findValue, + }; + } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; + } + } +} +export const deleteWallItems = async (data: IWallDelete): Promise => { + try { + const { modelUuid, modelName, organization, userId, projectId } = data; + const UserExists = await existingUser(userId, organization); + if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; + const findValue = await wallItemModel(organization).findOneAndDelete({ + modelUuid: modelUuid, + modelName: modelName, + projectId: projectId, + }); + if (!findValue) { + return { + status: "model not found", + }; + } else { + return { + status: "Success", + data: findValue, + }; + } + } catch (error: unknown) { + if (error instanceof Error) { + return { + status: error.message, + }; + } else { + return { + status: "An unexpected error occurred", + }; } } } diff --git a/src/shared/services/builder/zoneService.ts b/src/shared/services/builder/zoneService.ts index 9174dfe..caf6eb0 100644 --- a/src/shared/services/builder/zoneService.ts +++ b/src/shared/services/builder/zoneService.ts @@ -4,7 +4,7 @@ import floatWidgetModel from "../../V1Models/Vizualization/floatWidget.ts"; import panelModel from "../../V1Models/Vizualization/panelmodel.ts"; import templateModel from "../../V1Models/Vizualization/templatemodel.ts"; import widgetModel from "../../V1Models/Vizualization/widgemodel.ts"; -import { existingUser } from "../helpers/v1projecthelperFns.ts"; +import { existingProjectById, existingUser } from "../helpers/v1projecthelperFns.ts"; interface ISetZone { organization: string; projectId: string; @@ -50,6 +50,12 @@ export const SetZone = async (data: ISetZone): Promise => { const viewPortposition = zoneData.viewPortposition; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const findZoneId = await zoneModel(organization).findOne({ projectId: projectId, zoneId: zoneId, @@ -105,6 +111,12 @@ export const DelZone = async (data: IZone): Promise => { }); const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; if (findZoneId) { const deleteZone = await zoneModel(organization) .findOneAndDelete({ @@ -203,6 +215,12 @@ export const ZoneData = async (data: IZone): Promise => { const { organization, userId, projectId, zoneId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const findZone = await zoneModel(organization).findOne({ zoneId: zoneId, projectId: projectId, @@ -233,6 +251,12 @@ export const SingleZonePanelData = async (data: IZone): Promise => { const { organization, userId, projectId, zoneId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const existingZone = await zoneModel(organization) .findOne({ projectId: projectId, @@ -301,6 +325,12 @@ export const VizZoneDatas = async (data: IVizZone): Promise => { const { organization, userId, projectId } = data; const UserExists = await existingUser(userId, organization); if (!UserExists) return { status: "User not found" }; + const LivingProject = await existingProjectById( + projectId, + organization, + userId + ); + if (!LivingProject) return { status: "Project not found" }; const existingZones = await zoneModel(organization) .find({ projectId: projectId, diff --git a/src/socket-server/controllers/builderController/asset-Controller.ts b/src/socket-server/controllers/builderController/asset-Controller.ts new file mode 100644 index 0000000..017ba1d --- /dev/null +++ b/src/socket-server/controllers/builderController/asset-Controller.ts @@ -0,0 +1,216 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { deleteAssetModel, replaceEventDatas, setAssetModel } from "../../../shared/services/builder/assetService.ts"; +export const setAssetHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setAssetModel_v1 || !data?.organization) return; + const requiredFields = [ + "modelUuid", + "modelName", + "position", + "rotation", + "eventData", + "modelfileID", + "isLocked", + "isVisible", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await setAssetModel(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Model created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Updated successfully": { message: "Updated successfully" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Asset_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Asset_Datas ? { data: Asset_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1UpdateResponse, response, connectedUsersByOrg) +} +export const deleteAssetHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.delete_v1AssetModel || !data?.organization) return; + const requiredFields = [ + "modelUuid", + "modelName", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1DeleteResponse, response, connectedUsersByOrg) + return; + } + const result = await deleteAssetModel(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Model deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "model not found": { message: "model not found" }, + "Failed to archive asset": { message: "Failed to archive asset" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Asset_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Asset_Datas ? { data: Asset_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1DeleteResponse, response, connectedUsersByOrg) +} +export const replaceEventDatasHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.asset_v1EventData || !data?.organization) return; + const requiredFields = [ + "modelUuid", + "eventData", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1EventDataResponse, response, connectedUsersByOrg) + return; + } + const result = await replaceEventDatas(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Data updated successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Model not for this UUID": { message: "Model not for this UUID" }, + "Failed to archive asset": { message: "Failed to archive asset" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Asset_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Asset_Datas ? { data: Asset_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.asset_v1EventDataResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/builderController/camera-Controller.ts b/src/socket-server/controllers/builderController/camera-Controller.ts new file mode 100644 index 0000000..3f55328 --- /dev/null +++ b/src/socket-server/controllers/builderController/camera-Controller.ts @@ -0,0 +1,73 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { SetCamera } from "../../../shared/services/builder/cameraService.ts"; +export const SetCameraHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setCamera_v1 || !data?.organization) return; + const requiredFields = [ + "position", + "target", + "rotation", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.camera_v1CreateResponse, response, connectedUsersByOrg) + return; + } + const result = await SetCamera(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Camera created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Update Success": { message: "Update Success" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Camera_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Camera_Datas ? { data: Camera_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.camera_v1CreateResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/builderController/environment-Controller.ts b/src/socket-server/controllers/builderController/environment-Controller.ts new file mode 100644 index 0000000..adf08e8 --- /dev/null +++ b/src/socket-server/controllers/builderController/environment-Controller.ts @@ -0,0 +1,72 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { SetCamera } from "../../../shared/services/builder/cameraService.ts"; +import { setEnvironment } from "../../../shared/services/builder/EnvironmentService.ts"; +export const setEnvironmentHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setenvironment_v1 || !data?.organization) return; + const requiredFields = [ + "roofVisibility", "wallVisibility", "shadowVisibility", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.Environment_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await setEnvironment(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "evironment created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + 'evironments updated': { message: 'evironments updated' }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Camera_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Camera_Datas ? { data: Camera_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.Environment_v1UpdateResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/builderController/line-Controller.ts b/src/socket-server/controllers/builderController/line-Controller.ts new file mode 100644 index 0000000..d510209 --- /dev/null +++ b/src/socket-server/controllers/builderController/line-Controller.ts @@ -0,0 +1,341 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { CreateLineItems, DeleteLayer, DeleteLineItems, DeleteLinePoints, UpdateLineItems } from "../../../shared/services/builder/lineService.ts"; +export const CreateLineHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.createLine_v1 || !data?.organization) return; + const requiredFields = [ + "line", + "type", + "layer", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.createLine_v1Response, response, connectedUsersByOrg) + return; + } + const result = await CreateLineItems(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "line created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Update Success": { message: "Update Success" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Line_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Line_Datas ? { data: Line_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.createLine_v1Response, response, connectedUsersByOrg) +} +export const UpdateLineHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.updateLine_v1 || !data?.organization) return; + const requiredFields = [ + "uuid", + "position", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.updateLine_v1Response, response, connectedUsersByOrg) + return; + } + const result = await UpdateLineItems(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "line updated successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Line_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Line_Datas ? { data: Line_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.updateLine_v1Response, response, connectedUsersByOrg) +} +export const DeleteLineHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteLine_v1 || !data?.organization) return; + const requiredFields = [ + "uuid", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deleteLine_v1Response, response, connectedUsersByOrg) + return; + } + const result = await DeleteLineItems(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "line deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "line not found": { message: "line not found" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Line_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Line_Datas ? { data: Line_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deleteLine_v1Response, response, connectedUsersByOrg) +} +export const DeleteLayerHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteLineLayer_v1 || !data?.organization) return; + const requiredFields = [ + "layer", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deleteLineLayer_v1Response, response, connectedUsersByOrg) + return; + } + const result = await DeleteLayer(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "layer deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "layer not found": { message: "layer not found" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Line_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Line_Datas ? { data: Line_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deleteLineLayer_v1Response, response, connectedUsersByOrg) +} +export const DeleteLinePointsHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deletePoint_v1 || !data?.organization) return; + const requiredFields = [ + "uuid", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deletePoint_v1Response, response, connectedUsersByOrg) + return; + } + const result = await DeleteLinePoints(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "layer deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Line not found": { message: "Line not found" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Line_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Line_Datas ? { data: Line_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deletePoint_v1Response, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/builderController/wall-Controller.ts b/src/socket-server/controllers/builderController/wall-Controller.ts new file mode 100644 index 0000000..05441f1 --- /dev/null +++ b/src/socket-server/controllers/builderController/wall-Controller.ts @@ -0,0 +1,147 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { deleteWallItems, setWallItems } from "../../../shared/services/builder/wallService.ts"; + +export const setWallItemsHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setWallItems_v1 || !data?.organization) return; + const requiredFields = [ + "modelUuid", + "modelName", + "position", + "type", + "csgposition", + "csgscale", + "quaternion", + "scale", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.wallItems_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await setWallItems(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "wall Item created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "Updated successfully": { message: "Updated successfully" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Camera_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Camera_Datas ? { data: Camera_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.wallItems_v1UpdateResponse, response, connectedUsersByOrg) +} +export const deleteWallItemsHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setWallItems_v1 || !data?.organization) return; + const requiredFields = [ + "modelUuid", + "modelName", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.wallItems_v1DeleteResponse, response, connectedUsersByOrg) + return; + } + const result = await deleteWallItems(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "wall Item deleted successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "model not found": { message: "model not found" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Camera_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Camera_Datas ? { data: Camera_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.wallItems_v1DeleteResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/builderController/zone-Controller.ts b/src/socket-server/controllers/builderController/zone-Controller.ts new file mode 100644 index 0000000..d9c3d0d --- /dev/null +++ b/src/socket-server/controllers/builderController/zone-Controller.ts @@ -0,0 +1,140 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { DelZone, SetZone } from "../../../shared/services/builder/zoneService.ts"; + + +export const SetZoneHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.setZone_v1 || !data?.organization) return; + const requiredFields = [ + "zoneData", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.zone_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await SetZone(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "zone created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + "zone updated": { message: "zone updated" }, + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Camera_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Camera_Datas ? { data: Camera_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.zone_v1UpdateResponse, response, connectedUsersByOrg) +} +export const DeleteZoneHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteZone_v1 || !data?.organization) return; + const requiredFields = [ + "zoneId", + "projectId", + "userId", + "organization", + ]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.Zone_v1DeleteResponse, response, connectedUsersByOrg) + return; + } + const result = await DelZone(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "zone deleted created successfully" }, + "User not found": { message: "User not found" }, + "Project not found": { message: "Project not found" }, + + + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Camera_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Camera_Datas ? { data: Camera_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.Zone_v1DeleteResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/project/projectController.ts b/src/socket-server/controllers/projectController/projectController.ts similarity index 100% rename from src/socket-server/controllers/project/projectController.ts rename to src/socket-server/controllers/projectController/projectController.ts diff --git a/src/socket-server/controllers/vizualizationController/3dWidget-Controller.ts b/src/socket-server/controllers/vizualizationController/3dWidget-Controller.ts new file mode 100644 index 0000000..2dd5326 --- /dev/null +++ b/src/socket-server/controllers/vizualizationController/3dWidget-Controller.ts @@ -0,0 +1,186 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { Add3DWidget, Delete3Dwidget, Update3Dwidget } from "../../../shared/services/visualization/widget3dService.ts"; +export const add3DwidgetHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.addWidget3D || !data?.organization) return; + const requiredFields = ["projectId", "userId", "organization", "zoneId", "widget"]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.addWidget3DResponse, response, connectedUsersByOrg) + return; + } + const result = await Add3DWidget(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Widget created successfully" }, + "User not found": { message: "User not found" }, + "Zone not found for the zoneId": { message: "Zone not found for the zoneId" }, + "3dwidget update successfully": { message: "widget update successfully" }, + "3dWidget not updated": { message: "3dWidget not updated" }, + "Widget 3d not created": { message: "Widget 3d not created" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const widgemodel3D_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(widgemodel3D_Datas ? { data: widgemodel3D_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.addWidget3DResponse, response, connectedUsersByOrg) +} +export const update3DHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.updateWidget3DPosition || !data?.organization) return; + const requiredFields = ["projectId", "id", "position", "rotation", "userId", "organization", "zoneId", "widget"]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.updateWidget3DPositionResponse, response, connectedUsersByOrg) + return; + } + const result = await Update3Dwidget(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "widget update successfully" }, + "User not found": { message: "User not found" }, + "Zone not found": { message: "Zone not found" }, + "Widget not updated": { message: "Widget not updated" }, + "widget not found": { message: "widget not found" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const widget3D_Datas = + status === "Success" && result?.data + + ? { + // const updateDatas = { + // widget: { + // id: update3dwidget.widgetID, + // type: update3dwidget.type, + // position: update3dwidget.position, + // rotation: update3dwidget.rotation, + // }, + // zoneId: zoneId, + // }; + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(widget3D_Datas ? { data: widget3D_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.updateWidget3DPositionResponse, response, connectedUsersByOrg) +} +export const Delete3DwidgetHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteWidget3D || !data?.organization) return; + const requiredFields = ["projectId", "id", "userId", "organization", "zoneId",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deletewidget3DResponse, response, connectedUsersByOrg) + return; + } + const result = await Delete3Dwidget(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "3DWidget delete unsuccessfull" }, + "User not found": { message: "User not found" }, + "Zone not found": { message: "Zone not found" }, + "3D widget not found for the ID": { message: "3D widget not found for the ID" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const widget3D_Datas = + status === "Success" && result?.data + + ? { + // const delete_Datas = { + // zoneId: zoneId, + // id: existing3Dwidget.widgetID, + // }; + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(widget3D_Datas ? { data: widget3D_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deletewidget3DResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/vizualizationController/floatWidget-Controller.ts b/src/socket-server/controllers/vizualizationController/floatWidget-Controller.ts new file mode 100644 index 0000000..d767e6f --- /dev/null +++ b/src/socket-server/controllers/vizualizationController/floatWidget-Controller.ts @@ -0,0 +1,187 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { AddFloat, DelFloat, DuplicateFloat } from "../../../shared/services/visualization/floatWidgetService.ts"; +export const AddFloatHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.addFloat_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "index", "widget", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.float_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await AddFloat(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "FloatWidget created successfully" }, + "User not found": { message: "User not found" }, + "Zone not found for the zoneId": { message: "Zone not found for the zoneId" }, + "Widget updated successfully": { message: "Widget updated successfully" }, + "Failed to create FloatWidget": { message: "Failed to create FloatWidget" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const fload_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(fload_Datas ? { data: fload_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.float_v1UpdateResponse, response, connectedUsersByOrg) +} +export const DeleteFloatHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteFloat_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "floatWidgetID", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.float_v1DeleteResponse, response, connectedUsersByOrg) + return; + } + const result = await DelFloat(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "FloatingWidget deleted successfully" }, + "User not found": { message: "User not found" }, + "Zone not found for the zoneId": { message: "Zone not found for the zoneId" }, + "FloatWidget not found for the Id": { message: "FloatWidget not found for the Id" }, + "FloatWidget not deleted": { message: "FloatWidget not deleted" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const fload_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(fload_Datas ? { data: fload_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.float_v1DeleteResponse, response, connectedUsersByOrg) +} +export const DuplicateFloatHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.duplicatefloat_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "index", "widget", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.duplicatefloat_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await DuplicateFloat(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "duplicate FloatWidget created successfully" }, + "User not found": { message: "User not found" }, + "Zone not found for the zoneId": { message: "Zone not found for the zoneId" }, + "FloatWidget update unsuccessfull": { message: "FloatWidget update unsuccessfull" }, + "FloatWidget not deleted": { message: "FloatWidget not deleted" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const fload_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(fload_Datas ? { data: fload_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.duplicatefloat_v1UpdateResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/vizualizationController/panel-Controller.ts b/src/socket-server/controllers/vizualizationController/panel-Controller.ts new file mode 100644 index 0000000..772bce0 --- /dev/null +++ b/src/socket-server/controllers/vizualizationController/panel-Controller.ts @@ -0,0 +1,247 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { AddPanel, ClearPanel, DelPanel, LockedPanel } from "../../../shared/services/visualization/panelService.ts"; +export const AddPanelHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.addPanel_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "panelOrder", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.addPanel_v1Response, response, connectedUsersByOrg) + return; + } + const result = await AddPanel(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Panels created successfully" }, + "User not found": { message: "User not found" }, + "Zone not found": { message: "Zone not found" }, + "No new panels were created. All panels already exist": { message: "No new panels were created. All panels already exist" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.addPanel_v1Response, response, connectedUsersByOrg) +} +export const DeletePanelHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deletePanel_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "panelName", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deletePanel_v1Response, response, connectedUsersByOrg) + return; + } + const result = await DelPanel(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Panel deleted successfully" }, + "User not found": { message: "User not found" }, + "Zone not found": { message: "Zone not found" }, + "Panel Already Deleted": { message: "Panel Already Deleted" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.deletePanel_v1Response, response, connectedUsersByOrg) +} +export const ClearPanelHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.clearPanel_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "panelName", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.clearPanel_v1Response, response, connectedUsersByOrg) + return; + } + const result = await ClearPanel(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "PanelWidgets cleared successfully" }, + "User not found": { message: "User not found" }, + "Zone not found": { message: "Zone not found" }, + "Requested Panel not found": { message: "Requested Panel not found" }, + "No widgets to clear": { message: "No widgets to clear" }, + "Failed to clear widgets in panel": { message: "Failed to clear widgets in panel" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.clearPanel_v1Response, response, connectedUsersByOrg) +} +export const LockedPanelHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.lockedPanel_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "lockedPanel", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.lockedPanel_v1Response, response, connectedUsersByOrg) + return; + } + const result = await LockedPanel(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "PanelWidgets cleared successfully" }, + "User not found": { message: "User not found" }, + "Zone not found": { message: "Zone not found" }, + "locked panel not updated": { message: "locked panel not updated" }, + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.lockedPanel_v1Response, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/vizualizationController/template-Controller.ts b/src/socket-server/controllers/vizualizationController/template-Controller.ts new file mode 100644 index 0000000..40cac71 --- /dev/null +++ b/src/socket-server/controllers/vizualizationController/template-Controller.ts @@ -0,0 +1,189 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { AddTemplate, AddTemplateToZone, TemplateDelete } from "../../../shared/services/visualization/templateService.ts"; +export const AddTemplateHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.addTemplate_v1 || !data?.organization) return; + const requiredFields = ["template", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.template_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await AddTemplate(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Panels created successfully" }, + "User not found": { message: "User not found" }, + "TemplateID alreay exists": { message: "TemplateID alreay exists" }, + "Template not saved": { message: "Template not saved" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.template_v1UpdateResponse, response, connectedUsersByOrg) +} +export const addTemplateZoneHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.addTemplateZone_v1 || !data?.organization) return; + const requiredFields = ["template", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.addTemplateZone_v1Response, response, connectedUsersByOrg) + return; + } + const result = await AddTemplateToZone(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Template placed in Zone" }, + "User not found": { message: "User not found" }, + "Zone not found ": { message: "Zone not found " }, + "TemplateID not found": { message: "TemplateID not found" }, + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // const templateZoneDatas = { + // template: { + // id: existingTemplate.templateID, + // name: existingTemplate.templateName, + // panelOrder: existingTemplate.panelOrder, + // widgets: existingTemplate.widgets, + // snapshot: existingTemplate.snapshot, + // floatingWidget: existingTemplate.floatWidgets, + // }, + // zoneId: existingZone.zoneId, + // zoneName: existingZone.zoneName, + // }; + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.addTemplateZone_v1Response, response, connectedUsersByOrg) +} +export const TemplateDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteTemplate_v1 || !data?.organization) return; + const requiredFields = ["templateID", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.TemplateDelete_v1Response, response, connectedUsersByOrg) + return; + } + const result = await TemplateDelete(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Template deleted successfully" }, + "User not found": { message: "User not found" }, + "Template not Deleted": { message: "Template not Deleted" }, + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const Panel_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(Panel_Datas ? { data: Panel_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.TemplateDelete_v1Response, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/controllers/vizualizationController/widget-Controller.ts b/src/socket-server/controllers/vizualizationController/widget-Controller.ts new file mode 100644 index 0000000..f84f508 --- /dev/null +++ b/src/socket-server/controllers/vizualizationController/widget-Controller.ts @@ -0,0 +1,128 @@ +import { Socket, Server } from "socket.io"; +import { EVENTS } from "../../socket/events.ts"; +import { emitToSenderAndAdmins } from "../../utils/emitEventResponse.ts"; +import { AddWidget, WidgetDelete } from "../../../shared/services/visualization/widgetService.ts"; +export const AddWidgetHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.addWidget_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "widget", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.widget_v1UpdateResponse, response, connectedUsersByOrg) + return; + } + const result = await AddWidget(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Widget created successfully" }, + "User not found": { message: "User not found" }, + "Zone not found for the zoneId": { message: "Zone not found for the zoneId" }, + "panelName not found": { message: "panelName not found" }, + "Widget update unsuccessfull": { message: "Widget update unsuccessfull" }, + "Type mismatch": { message: "Type mismatch" }, + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const widget_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(widget_Datas ? { data: widget_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.widget_v1UpdateResponse, response, connectedUsersByOrg) +} +export const WidgetDeleteHandleEvent = async ( + event: string, + socket: Socket, + io: Server, + data: any, + connectedUsersByOrg: { [org: string]: { socketId: string; userId: string; role: string }[] }, +) => { + if (event !== EVENTS.deleteWidget_v1 || !data?.organization) return; + const requiredFields = ["zoneId", "widgetID", "projectId", "userId", "organization",]; + const missingFields = requiredFields.filter(field => !data?.[field]); + + if (missingFields.length > 0) { + const response = { + success: false, + message: `Missing required field(s): ${missingFields.join(", ")}`, + status: "MissingFields", + socketId: socket.id, + organization: data?.organization ?? "unknown", + }; + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.widget_v1DeleteResponse, response, connectedUsersByOrg) + return; + } + const result = await WidgetDelete(data); + const status = typeof result?.status === "string" ? result.status : "unknown"; + + const messages: Record = { + Success: { message: "Widget deleted successfully" }, + "User not found": { message: "User not found" }, + "Zone not found for the zoneId": { message: "Zone not found for the zoneId" }, + "Widget not found": { message: "Widget not found" }, + + }; + + const msg = messages[status] || { message: "Internal server error" }; + const widget_Datas = + status === "Success" && result?.data + + ? { + // widget: { + // id: result.data.widgetID, + // type: result.data.projectName, + // position: result.data.position, + // }, + // Data: result.data.Data, + // zoneId: result.data.zoneId, + } + : undefined; + + const response = { + success: status === "Success", + message: msg.message, + status, + socketId: socket.id, + organization: data.organization, + ...(widget_Datas ? { data: widget_Datas } : {}), + }; + + + emitToSenderAndAdmins(io, socket, data.organization, EVENTS.widget_v1DeleteResponse, response, connectedUsersByOrg) +} \ No newline at end of file diff --git a/src/socket-server/manager/manager.ts b/src/socket-server/manager/manager.ts index fe0adb2..02ddbd1 100644 --- a/src/socket-server/manager/manager.ts +++ b/src/socket-server/manager/manager.ts @@ -1,5 +1,16 @@ import { Server, Socket } from 'socket.io'; -import { projectDeleteHandleEvent, projectHandleEvent, projecUpdateHandleEvent } from '../controllers/project/projectController.ts'; +import { projectDeleteHandleEvent, projectHandleEvent, projecUpdateHandleEvent } from '../controllers/projectController/projectController.ts'; +import { setAssetHandleEvent, deleteAssetHandleEvent, replaceEventDatasHandleEvent } from '../controllers/builderController/asset-Controller.ts'; +import { SetCameraHandleEvent } from '../controllers/builderController/camera-Controller.ts'; +import { setEnvironmentHandleEvent } from '../controllers/builderController/environment-Controller.ts'; +import { CreateLineHandleEvent, UpdateLineHandleEvent, DeleteLineHandleEvent, DeleteLayerHandleEvent, DeleteLinePointsHandleEvent } from '../controllers/builderController/line-Controller.ts'; +import { deleteWallItemsHandleEvent, setWallItemsHandleEvent } from '../controllers/builderController/wall-Controller.ts'; +import { DeleteZoneHandleEvent, SetZoneHandleEvent } from '../controllers/builderController/zone-Controller.ts'; +import { add3DwidgetHandleEvent, Delete3DwidgetHandleEvent, update3DHandleEvent } from '../controllers/vizualizationController/3dWidget-Controller.ts'; +import { AddFloatHandleEvent, DeleteFloatHandleEvent, DuplicateFloatHandleEvent } from '../controllers/vizualizationController/floatWidget-Controller.ts'; +import { AddPanelHandleEvent, ClearPanelHandleEvent, DeletePanelHandleEvent, LockedPanelHandleEvent } from '../controllers/vizualizationController/panel-Controller.ts'; +import { AddTemplateHandleEvent, addTemplateZoneHandleEvent, TemplateDeleteHandleEvent } from '../controllers/vizualizationController/template-Controller.ts'; +import { AddWidgetHandleEvent, WidgetDeleteHandleEvent } from '../controllers/vizualizationController/widget-Controller.ts'; export const SocketServer = (httpServer: any) => { const io = new Server(httpServer, { @@ -10,28 +21,29 @@ export const SocketServer = (httpServer: any) => { }); - + const namespaces = { project: io.of('/project'), - + Builder: io.of("/Builder"), + visualization: io.of("/Visualization"), }; - + // const onlineUsers = new Map>(); const onlineUsers: { [organization: string]: Set } = {}; - const handleNamespace = ( namespace: any, ...eventHandlers: Function[]) => { - + const handleNamespace = (namespace: any, ...eventHandlers: Function[]) => { + namespace.on("connection", (socket: Socket) => { - console.log(`✅ Client connected to ${namespace.name}: ${socket.id}`); + console.log(`✅ Client connected to ${namespace.name}: ${socket.id}`); // Extract organization from query parameters - + const organization = socket.handshake.query.organization as string; const email = socket.handshake.query.email as string; - // const {organization,email} = socket.handshake.auth + // const {organization,email} = socket.handshake.auth console.log(`🔍 Received organization: ${organization}`); - + if (organization) { socket.join(organization); // console.log(`🔹 Socket ${socket.id} joined room: ${organization}`); @@ -39,40 +51,73 @@ export const SocketServer = (httpServer: any) => { // Handle all events if (organization && email) { if (!onlineUsers[organization]) { - onlineUsers[organization] = new Set(); + onlineUsers[organization] = new Set(); } onlineUsers[organization].add(socket.id); - - } - // userStatus(EVENTS.connection, socket, socket.handshake.auth, socket); + } - socket.onAny((event: string, data: any ,callback:any) => { - eventHandlers.forEach(handler => handler(event, socket, data, namespace,io,callback)); + // userStatus(EVENTS.connection, socket, socket.handshake.auth, socket); + + socket.onAny((event: string, data: any, callback: any) => { + eventHandlers.forEach(handler => handler(event, socket, data, namespace, io, callback)); }); - + // Handle disconnection socket.on("disconnect", () => { onlineUsers[organization]?.delete(socket.id); if (onlineUsers[organization]?.size === 0) delete onlineUsers[organization]; // userStatus(EVENTS.disconnect, socket, socket.handshake.auth, socket); - + }); - + // Handle reconnection (Auto rejoin) socket.on("reconnect", (attempt: number) => { - + if (organization) { socket.join(organization); - + } }); }); }; - -handleNamespace(namespaces.project,projectHandleEvent,projectDeleteHandleEvent,projecUpdateHandleEvent) + + handleNamespace(namespaces.project, projectHandleEvent, projectDeleteHandleEvent, projecUpdateHandleEvent) + handleNamespace(namespaces.Builder, + setAssetHandleEvent, + deleteAssetHandleEvent, + replaceEventDatasHandleEvent, + SetCameraHandleEvent, + setEnvironmentHandleEvent, + CreateLineHandleEvent, + UpdateLineHandleEvent, + DeleteLineHandleEvent, + DeleteLayerHandleEvent, + DeleteLinePointsHandleEvent, + setWallItemsHandleEvent, + deleteWallItemsHandleEvent, + SetZoneHandleEvent, + DeleteZoneHandleEvent + ) + handleNamespace(namespaces.visualization, + add3DwidgetHandleEvent, + update3DHandleEvent, + Delete3DwidgetHandleEvent, + AddFloatHandleEvent, + DeleteFloatHandleEvent, + DuplicateFloatHandleEvent, + AddPanelHandleEvent, + DeletePanelHandleEvent, + ClearPanelHandleEvent, + LockedPanelHandleEvent, + AddTemplateHandleEvent, + addTemplateZoneHandleEvent, + TemplateDeleteHandleEvent, + AddWidgetHandleEvent, + WidgetDeleteHandleEvent + ) return io; }; \ No newline at end of file diff --git a/src/socket-server/socket/events.ts b/src/socket-server/socket/events.ts index a152c8d..96b9024 100644 --- a/src/socket-server/socket/events.ts +++ b/src/socket-server/socket/events.ts @@ -1,9 +1,9 @@ export const EVENTS = { connection: "connection", - disconnect:"disconnect", + disconnect: "disconnect", //userActiveStatus - userConnect:"userConnectResponse", - userDisConnect:"userDisConnectResponse", + userConnect: "userConnectResponse", + userDisConnect: "userDisConnectResponse", // Room management events joinRoom: 'joinRoom', createroom: "createRoom", // When a client joins a room @@ -32,73 +32,73 @@ export const EVENTS = { wallItemsDeleteResponse: "wallItemsDeleteResponse", wallItemError: "wallItemError", //Lines - createLine:"v1:Line:create", - createLineResponse:"Line:response:create", - updateLine:"v1:Line:update", - updateLineResponse:"Line:response:update", - deleteLine:"v1:Line:delete", - deleteLineResponse:"Line:response:delete", - deletePoint:"v1:Line:delete:point", - deletePointResponse:"Line:response:delete:point", - deleteLineLayer:"v1:Line:delete:layer", - deleteLineLayerResponse:"Line:response:delete:layer", + createLine: "v1:Line:create", + createLineResponse: "Line:response:create", + updateLine: "v1:Line:update", + updateLineResponse: "Line:response:update", + deleteLine: "v1:Line:delete", + deleteLineResponse: "Line:response:delete", + deletePoint: "v1:Line:delete:point", + deletePointResponse: "Line:response:delete:point", + deleteLineLayer: "v1:Line:delete:layer", + deleteLineLayerResponse: "Line:response:delete:layer", //zone - setZone:"v2:zone:set", - zoneUpdateResponse:"zone:response:updates", - deleteZone:"v2:zone:delete", - ZoneDeleteResponse:"zone:response:delete", + setZone: "v2:zone:set", + zoneUpdateResponse: "zone:response:updates", + deleteZone: "v2:zone:delete", + ZoneDeleteResponse: "zone:response:delete", //visualization //panel - addPanel:"v2:viz-panel:add", - panelUpdateResponse:"viz-panel:response:updates", - deletePanel:"v2:viz-panel:delete", - PanelDeleteResponse:"viz-panel:response:delete", - clearPanel:"v2:viz-panel:clear", - PanelClearResponse:"viz-panel:response:clear", - lockedPanel:"v2:viz-panel:locked", - PanelLockedResponse:"viz-panel:response:locked", + addPanel: "v2:viz-panel:add", + panelUpdateResponse: "viz-panel:response:updates", + deletePanel: "v2:viz-panel:delete", + PanelDeleteResponse: "viz-panel:response:delete", + clearPanel: "v2:viz-panel:clear", + PanelClearResponse: "viz-panel:response:clear", + lockedPanel: "v2:viz-panel:locked", + PanelLockedResponse: "viz-panel:response:locked", //widget - addWidget:"v2:viz-widget:add", - widgetUpdateResponse:"viz-widget:response:updates", - deleteWidget:"v2:viz-widget:delete", - widgetDeleteResponse:"viz-widget:response:delete", + addWidget: "v2:viz-widget:add", + widgetUpdateResponse: "viz-widget:response:updates", + deleteWidget: "v2:viz-widget:delete", + widgetDeleteResponse: "viz-widget:response:delete", //float addFloat: "v2:viz-float:add", floatUpdateResponse: "viz-float:response:updates", deleteFloat: "v2:viz-float:delete", floatDeleteResponse: "viz-float:response:delete", - duplicatefloat:"v2:viz-float:addDuplicate", - duplicatefloatUpdateResponse:"viz-float:response:addDuplicate", + duplicatefloat: "v2:viz-float:addDuplicate", + duplicatefloatUpdateResponse: "viz-float:response:addDuplicate", //template - addTemplate:"v2:viz-template:add", - templateUpdateResponse:"viz-template:response:add", - addTemplateZone:"v2:viz-template:addToZone", - addTemplateZoneResponse:"viz-template:response:addTemplateZone", - deleteTemplate:"v2:viz-template:deleteTemplate", - TemplateDeleteResponse:"viz-template:response:delete", + addTemplate: "v2:viz-template:add", + templateUpdateResponse: "viz-template:response:add", + addTemplateZone: "v2:viz-template:addToZone", + addTemplateZoneResponse: "viz-template:response:addTemplateZone", + deleteTemplate: "v2:viz-template:deleteTemplate", + TemplateDeleteResponse: "viz-template:response:delete", //model-asset setAssetModel: "v2:model-asset:add", assetUpdateResponse: "model-asset:response:updates", - deleteAssetModel:"v2:model-asset:delete", + deleteAssetModel: "v2:model-asset:delete", assetDeleteResponse: "model-asset:response:updates", - assetEventData:"v2:model-asset:updateEventData", + assetEventData: "v2:model-asset:updateEventData", assetEventDataResponse: "model-asset:response:updateEventData", //3Dwidget - add3DWidget:"v2:viz-3D-widget:add", - widget3DUpdateResponse:"viz-widget3D:response:updates", - update3dPosition:"v2:viz-3D-widget:modifyPositionRotation", - update3dPositionResponse:"viz-widget3D:response:modifyPositionRotation", - delete3DWidget:"v2:viz-3D-widget:delete", - widget3DDeleteResponse:"viz-widget3D:response:delete", - + add3DWidget: "v2:viz-3D-widget:add", + widget3DUpdateResponse: "viz-widget3D:response:updates", + update3dPosition: "v2:viz-3D-widget:modifyPositionRotation", + update3dPositionResponse: "viz-widget3D:response:modifyPositionRotation", + delete3DWidget: "v2:viz-3D-widget:delete", + widget3DDeleteResponse: "viz-widget3D:response:delete", + //................................................... //PROJECT addProject: "v1:project:add", projectResponse: "v1-project:response:add", @@ -106,4 +106,79 @@ export const EVENTS = { deleteProjectResponse: "v1-project:response:delete", ProjectUpdate: "v1:project:update", projectUpdateResponse: "v1-project:response:update", + + //3Dwidget + addWidget3D: "v1:viz-3D-widget:add", + addWidget3DResponse: "v1:viz-widget3D:response:add", + updateWidget3DPosition: "v1:viz-3D-widget:modifyPositionRotation", + updateWidget3DPositionResponse: "v1:viz-widget3D:response:modifyPositionRotation", + deleteWidget3D: "v1:viz-3D-widget:delete", + deletewidget3DResponse: "v1:viz-widget3D:response:delete", + + //panel + addPanel_v1: "v1:viz-panel:add", + addPanel_v1Response: "v1:viz-panel:response:add", + deletePanel_v1: "v1:viz-panel:delete", + deletePanel_v1Response: "v1:viz-panel:response:delete", + clearPanel_v1: "v1:viz-panel:clear", + clearPanel_v1Response: "v1:viz-panel:response:clear", + lockedPanel_v1: "v1:viz-panel:locked", + lockedPanel_v1Response: "v1:viz-panel:response:locked", + //float + addFloat_v1: "v1:viz-float:add", + float_v1UpdateResponse: "v1:viz-float:response:updates", + deleteFloat_v1: "v1:viz-float:delete", + float_v1DeleteResponse: "v1:viz-float:response:delete", + duplicatefloat_v1: "v1:viz-float:addDuplicate", + duplicatefloat_v1UpdateResponse: "v1:viz-float:response:addDuplicate", + + //template + addTemplate_v1: "v1:viz-template:add", + template_v1UpdateResponse: "v1:viz-template:response:add", + addTemplateZone_v1: "v1:viz-template:addToZone", + addTemplateZone_v1Response: "v1:viz-template:response:addTemplateZone", + deleteTemplate_v1: "v1:viz-template:deleteTemplate", + TemplateDelete_v1Response: "v1:viz-template:response:delete", + + //widget + addWidget_v1: "v1:viz-widget:add", + widget_v1UpdateResponse: "v1:viz-widget:response:updates", + deleteWidget_v1: "v1:viz-widget:delete", + widget_v1DeleteResponse: "v1:viz-widget:response:delete", + //model-asset + setAssetModel_v1: "v1:model-asset:add", + asset_v1UpdateResponse: "v1:model-asset:response:updates", + delete_v1AssetModel: "v1:model-asset:delete", + asset_v1DeleteResponse: "v1:model-asset:response:updates", + asset_v1EventData: "v1:model-asset:updateEventData", + asset_v1EventDataResponse: "v1:model-asset:response:updateEventData", + // Camera + setCamera_v1: 'v1:Camera:set', + camera_v1CreateResponse: "v1:camera:Response:update", + //Lines + createLine_v1: "v1:Line:create", + createLine_v1Response: "v1:Line:response:create", + updateLine_v1: "v1:Line:update", + updateLine_v1Response: "v1:Line:response:update", + deleteLine_v1: "v1:Line:delete", + deleteLine_v1Response: "v1:Line:response:delete", + deletePoint_v1: "v1:Line:delete:point", + deletePoint_v1Response: "v1:Line:response:delete:point", + deleteLineLayer_v1: "v1:Line:delete:layer", + deleteLineLayer_v1Response: "v1:Line:response:delete:layer", + //Environment + setenvironment_v1: "v1:Environment:set", + Environment_v1UpdateResponse: "v1:EnvironmentUpdateResponse", + + //WALLItems + setWallItems_v1: "v1:wallItems:set", + wallItems_v1UpdateResponse: "v1:wallItemsUpdateResponse", + deleteWallItems_v1: "v1:wallItems:delete", + wallItems_v1DeleteResponse: "v1:wallItemsDeleteResponse", + //zone + setZone_v1: "v1:zone:set", + zone_v1UpdateResponse: "v1:zone:response:updates", + deleteZone_v1: "v1:zone:delete", + Zone_v1DeleteResponse: "v1:zone:response:delete", + } \ No newline at end of file diff --git a/src/socket-server/socket/socketManager.ts b/src/socket-server/socket/socketManager.ts index 83bc7dd..199f483 100644 --- a/src/socket-server/socket/socketManager.ts +++ b/src/socket-server/socket/socketManager.ts @@ -56,7 +56,7 @@ import { projectDeleteHandleEvent, projectHandleEvent, projecUpdateHandleEvent, -} from "../controllers/project/projectController.ts"; +} from "../controllers/projectController/projectController.ts"; import { getUserRole } from "../utils/getUsers.ts"; const cameraHandleEvent = async (