@lv-x-software-house/x_view 1.2.2-dev.6 → 1.2.2-dev.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1649,27 +1649,50 @@ var userActionHandlers = {
1649
1649
  setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
1650
1650
  },
1651
1651
  handleSaveNode: async (context, newNodeData) => {
1652
- const { graphDataRef, sceneDataRef, stateRef, creationMode, setters } = context;
1652
+ const { graphDataRef, sceneDataRef, stateRef, creationMode, setters, actions } = context;
1653
1653
  if (!graphDataRef.current || !sceneDataRef.current) return;
1654
1654
  const { sourceNodeData } = creationMode;
1655
- const newNode = { id: import_short_uuid.default.generate(), ...newNodeData };
1655
+ const { targetDatasetId, ...nodeDataToSave } = newNodeData;
1656
+ const newNode = { id: import_short_uuid.default.generate(), ...nodeDataToSave };
1656
1657
  const newLink = { id: `link_${import_short_uuid.default.generate()}`, source: sourceNodeData.id, target: newNode.id };
1657
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
1658
- if (!parentInfo || !parentInfo.ownerId) {
1659
- console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
1660
- alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
1658
+ const sourceParentInfo = stateRef.current.nodeIdToParentFileMap.get(String(sourceNodeData.id));
1659
+ const finalTargetDatasetId = targetDatasetId || sourceParentInfo.parentFileId;
1660
+ const targetParentInfo = sceneDataRef.current.parent_dbs.find((db) => String(db.db_id) === String(finalTargetDatasetId));
1661
+ if (!sourceParentInfo || !targetParentInfo) {
1662
+ alert("Erro ao identificar os datasets de origem ou destino.");
1661
1663
  return;
1662
1664
  }
1663
- const { parentFileId, ownerId } = parentInfo;
1664
- const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
1665
- specificParentData.nodes.push(newNode);
1666
- specificParentData.links.push(newLink);
1667
- const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
1665
+ const isCrossDataset = String(sourceParentInfo.parentFileId) !== String(finalTargetDatasetId);
1666
+ const sourceDataToUpdate = JSON.parse(JSON.stringify(graphDataRef.current[sourceParentInfo.parentFileId]));
1667
+ let targetDataToUpdate = isCrossDataset ? JSON.parse(JSON.stringify(graphDataRef.current[finalTargetDatasetId])) : sourceDataToUpdate;
1668
+ targetDataToUpdate.nodes.push(newNode);
1669
+ sourceDataToUpdate.links.push(newLink);
1670
+ const savePromises = [];
1671
+ if (isCrossDataset) {
1672
+ savePromises.push(
1673
+ actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
1674
+ );
1675
+ savePromises.push(
1676
+ actions.save_view_data(`x_view_dbs/${targetParentInfo.owner_id}/${finalTargetDatasetId}`, targetDataToUpdate)
1677
+ );
1678
+ } else {
1679
+ savePromises.push(
1680
+ actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
1681
+ );
1682
+ }
1668
1683
  try {
1669
- await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
1670
- graphDataRef.current[parentFileId] = specificParentData;
1684
+ await Promise.all(savePromises);
1685
+ graphDataRef.current[sourceParentInfo.parentFileId] = sourceDataToUpdate;
1686
+ if (isCrossDataset) {
1687
+ graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
1688
+ }
1671
1689
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1672
1690
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
1691
+ stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
1692
+ parentFileId: finalTargetDatasetId,
1693
+ ownerId: targetParentInfo.owner_id,
1694
+ datasetName: targetDataToUpdate.dataset_name || "Dataset Desconhecido"
1695
+ });
1673
1696
  setters.setSceneVersion((v) => v + 1);
1674
1697
  } catch (error) {
1675
1698
  console.error("Falha ao salvar os dados do grafo:", error);
@@ -6779,7 +6802,11 @@ function InSceneCreationForm({
6779
6802
  availableAncestries = [],
6780
6803
  onMentionClick,
6781
6804
  sourceTypes,
6782
- onUploadFile
6805
+ onUploadFile,
6806
+ // Props do Dataset adicionadas
6807
+ availableDatasets = [],
6808
+ sourceNodeDatasetId,
6809
+ viewType
6783
6810
  }) {
6784
6811
  const [name, setName] = (0, import_react13.useState)("");
6785
6812
  const [types, setTypes] = (0, import_react13.useState)([]);
@@ -6794,6 +6821,10 @@ function InSceneCreationForm({
6794
6821
  const [isDescriptionModalOpen, setIsDescriptionModalOpen] = (0, import_react13.useState)(false);
6795
6822
  const [useImageAsTexture, setUseImageAsTexture] = (0, import_react13.useState)(false);
6796
6823
  const [selectedImageUrl, setSelectedImageUrl] = (0, import_react13.useState)(null);
6824
+ const [targetDatasetId, setTargetDatasetId] = (0, import_react13.useState)(sourceNodeDatasetId || "");
6825
+ (0, import_react13.useEffect)(() => {
6826
+ if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
6827
+ }, [sourceNodeDatasetId]);
6797
6828
  const propsEndRef = (0, import_react13.useRef)(null);
6798
6829
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
6799
6830
  (0, import_react13.useEffect)(() => {
@@ -6911,6 +6942,8 @@ function InSceneCreationForm({
6911
6942
  description_sections: processedSections,
6912
6943
  useImageAsTexture,
6913
6944
  textureImageUrl: useImageAsTexture ? selectedImageUrl : null,
6945
+ targetDatasetId,
6946
+ // Alvo do Dataset adicionado no onSave
6914
6947
  ...additionalData
6915
6948
  });
6916
6949
  };
@@ -6988,7 +7021,15 @@ function InSceneCreationForm({
6988
7021
  }
6989
7022
  },
6990
7023
  suggestedType
6991
- ))))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ import_react13.default.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react13.default.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react13.default.createElement(
7024
+ ))))), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ import_react13.default.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), viewType === "view" && availableDatasets.length > 0 && /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Criar Node no Dataset:"), /* @__PURE__ */ import_react13.default.createElement(
7025
+ "select",
7026
+ {
7027
+ value: targetDatasetId,
7028
+ onChange: (e) => setTargetDatasetId(e.target.value),
7029
+ className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 text-slate-200 cursor-pointer appearance-none"
7030
+ },
7031
+ availableDatasets.map((ds) => /* @__PURE__ */ import_react13.default.createElement("option", { key: ds.id, value: ds.id }, ds.name))
7032
+ )), /* @__PURE__ */ import_react13.default.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ import_react13.default.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ import_react13.default.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ import_react13.default.createElement(
6992
7033
  DescriptionDisplay,
6993
7034
  {
6994
7035
  description,
@@ -7324,7 +7365,9 @@ function NodeDetailsPanel({
7324
7365
  onMentionClick,
7325
7366
  onIntensityChange,
7326
7367
  onUploadFile,
7327
- userRole
7368
+ userRole,
7369
+ currentDatasetName
7370
+ // Prop currentDatasetName adicionada
7328
7371
  }) {
7329
7372
  const [name, setName] = (0, import_react15.useState)((node == null ? void 0 : node.name) ?? "");
7330
7373
  const [types, setTypes] = (0, import_react15.useState)([]);
@@ -7735,7 +7778,7 @@ function NodeDetailsPanel({
7735
7778
  onUploadFile: canEdit ? onUploadFile : void 0,
7736
7779
  readOnly: !canEdit
7737
7780
  }
7738
- )), /* @__PURE__ */ import_react15.default.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react15.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react15.default.createElement(
7781
+ )), /* @__PURE__ */ import_react15.default.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ import_react15.default.createElement("div", { className: "pt-2 mt-4 border-t border-white/10" }, /* @__PURE__ */ import_react15.default.createElement("label", { className: "text-[10px] uppercase text-slate-400 font-semibold tracking-wider" }, "Hospedado no Dataset"), /* @__PURE__ */ import_react15.default.createElement("div", { className: "flex items-center gap-2 mt-1.5 px-3 py-2 bg-slate-800/40 rounded-lg border border-white/5" }, /* @__PURE__ */ import_react15.default.createElement(import_fi14.FiDatabase, { className: "text-indigo-400", size: 14 }), /* @__PURE__ */ import_react15.default.createElement("span", { className: "text-xs text-slate-300 truncate font-medium" }, currentDatasetName)))), /* @__PURE__ */ import_react15.default.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ import_react15.default.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ import_react15.default.createElement(
7739
7782
  "button",
7740
7783
  {
7741
7784
  onClick: () => handleSave(false),
@@ -9056,7 +9099,7 @@ function XViewScene({
9056
9099
  delete_file_action,
9057
9100
  check_user_permission
9058
9101
  }) {
9059
- var _a, _b, _c, _d, _e, _f;
9102
+ var _a, _b, _c, _d, _e, _f, _g;
9060
9103
  const { data: session, status } = (0, import_react24.useSession)();
9061
9104
  const router = (0, import_navigation.useRouter)();
9062
9105
  const searchParams = (0, import_navigation.useSearchParams)();
@@ -9208,9 +9251,10 @@ function XViewScene({
9208
9251
  const parentFile = allParentData[parentFileId];
9209
9252
  const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
9210
9253
  const ownerId2 = (parentDbInfo == null ? void 0 : parentDbInfo.owner_id) || null;
9254
+ const datasetName = parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
9211
9255
  if (parentFile.nodes && ownerId2) {
9212
9256
  for (const node of parentFile.nodes) {
9213
- map.set(String(node.id), { parentFileId, ownerId: ownerId2 });
9257
+ map.set(String(node.id), { parentFileId, ownerId: ownerId2, datasetName });
9214
9258
  }
9215
9259
  }
9216
9260
  }
@@ -9730,6 +9774,9 @@ function XViewScene({
9730
9774
  sceneDataRef.current = sceneResponse.data.scene;
9731
9775
  parentDataRef.current = sceneResponse.data.parent;
9732
9776
  ancestryDataRef.current = sceneResponse.data.ancestry;
9777
+ console.log("Console de sceneResponse.data.scene:", sceneResponse.data.scene);
9778
+ console.log("Console de sceneResponse.data.parent:", sceneResponse.data.parent);
9779
+ console.log("Console de sceneResponse.data.ancestry:", sceneResponse.data.ancestry);
9733
9780
  setIsInitialized(true);
9734
9781
  } else {
9735
9782
  console.error("Falha ao buscar dados da cena:", (sceneResponse == null ? void 0 : sceneResponse.error) || "Resposta inv\xE1lida.");
@@ -12056,6 +12103,18 @@ function XViewScene({
12056
12103
  tweenToTarget(nodeMesh, 1.2);
12057
12104
  }
12058
12105
  }, [tweenToTarget]);
12106
+ const availableDatasets = (0, import_react23.useMemo)(() => {
12107
+ if (!sceneDataRef.current || !parentDataRef.current) return [];
12108
+ return sceneDataRef.current.parent_dbs.map((db) => {
12109
+ var _a2;
12110
+ return {
12111
+ id: db.db_id,
12112
+ name: ((_a2 = parentDataRef.current[db.db_id]) == null ? void 0 : _a2.dataset_name) || `Dataset #${db.db_id.substring(0, 6)}`
12113
+ };
12114
+ });
12115
+ }, [sceneVersion, isInitialized]);
12116
+ const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
12117
+ const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
12059
12118
  (0, import_react23.useEffect)(() => {
12060
12119
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
12061
12120
  const nodeObjects = stateRef.current.nodeObjects || {};
@@ -12145,10 +12204,13 @@ function XViewScene({
12145
12204
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12146
12205
  refEl: formRef,
12147
12206
  existingTypes: existingNodeTypes,
12148
- initialColor: (_b = creationMode.sourceNodeData) == null ? void 0 : _b.color,
12149
- sourceTypes: (_c = creationMode.sourceNodeData) == null ? void 0 : _c.type,
12207
+ initialColor: (_c = creationMode.sourceNodeData) == null ? void 0 : _c.color,
12208
+ sourceTypes: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.type,
12150
12209
  onIntensityChange: handleGhostNodeIntensityChange,
12151
- onUploadFile: upload_file_action
12210
+ onUploadFile: upload_file_action,
12211
+ availableDatasets,
12212
+ sourceNodeDatasetId,
12213
+ viewType: viewParams == null ? void 0 : viewParams.type
12152
12214
  }
12153
12215
  ),
12154
12216
  versionMode.isActive && /* @__PURE__ */ import_react23.default.createElement(
@@ -12163,8 +12225,8 @@ function XViewScene({
12163
12225
  onMentionClick: handleAddExistingNode,
12164
12226
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12165
12227
  refEl: formRef,
12166
- fixedType: (_d = versionMode.sourceNodeData) == null ? void 0 : _d.type,
12167
- fixedColor: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.color,
12228
+ fixedType: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.type,
12229
+ fixedColor: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.color,
12168
12230
  onUploadFile: upload_file_action
12169
12231
  }
12170
12232
  ),
@@ -12273,7 +12335,8 @@ function XViewScene({
12273
12335
  onMentionClick: handleAddExistingNode,
12274
12336
  onIntensityChange: handleDetailNodeIntensityChange,
12275
12337
  onUploadFile: upload_file_action,
12276
- userRole: userPermissionRole
12338
+ userRole: userPermissionRole,
12339
+ currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
12277
12340
  }
12278
12341
  ),
12279
12342
  detailsLink && /* @__PURE__ */ import_react23.default.createElement(
@@ -12401,7 +12464,7 @@ function XViewScene({
12401
12464
  onClose: () => setIsImportModalOpen(false),
12402
12465
  onConfirm: handleConfirmImport,
12403
12466
  session,
12404
- parentDbs: ((_f = sceneDataRef.current) == null ? void 0 : _f.parent_dbs) || [],
12467
+ parentDbs: ((_g = sceneDataRef.current) == null ? void 0 : _g.parent_dbs) || [],
12405
12468
  onFetchAvailableFiles: import_parent_file_modal_get,
12406
12469
  currentViewName: viewParams == null ? void 0 : viewParams.name,
12407
12470
  currentAncestries: ancestryDataRef.current || []
package/dist/index.mjs CHANGED
@@ -1605,27 +1605,50 @@ var userActionHandlers = {
1605
1605
  setters.setFormPosition((p) => ({ ...p, opacity: 0 }));
1606
1606
  },
1607
1607
  handleSaveNode: async (context, newNodeData) => {
1608
- const { graphDataRef, sceneDataRef, stateRef, creationMode, setters } = context;
1608
+ const { graphDataRef, sceneDataRef, stateRef, creationMode, setters, actions } = context;
1609
1609
  if (!graphDataRef.current || !sceneDataRef.current) return;
1610
1610
  const { sourceNodeData } = creationMode;
1611
- const newNode = { id: short.generate(), ...newNodeData };
1611
+ const { targetDatasetId, ...nodeDataToSave } = newNodeData;
1612
+ const newNode = { id: short.generate(), ...nodeDataToSave };
1612
1613
  const newLink = { id: `link_${short.generate()}`, source: sourceNodeData.id, target: newNode.id };
1613
- const parentInfo = getParentFileInfoForNode(graphDataRef.current, sceneDataRef.current, sourceNodeData.id);
1614
- if (!parentInfo || !parentInfo.ownerId) {
1615
- console.error("N\xE3o foi poss\xEDvel encontrar as informa\xE7\xF5es do arquivo pai (ou ownerId) para o Node de origem:", sourceNodeData.id);
1616
- alert("Ocorreu um erro ao identificar o arquivo pai ou seu propriet\xE1rio.");
1614
+ const sourceParentInfo = stateRef.current.nodeIdToParentFileMap.get(String(sourceNodeData.id));
1615
+ const finalTargetDatasetId = targetDatasetId || sourceParentInfo.parentFileId;
1616
+ const targetParentInfo = sceneDataRef.current.parent_dbs.find((db) => String(db.db_id) === String(finalTargetDatasetId));
1617
+ if (!sourceParentInfo || !targetParentInfo) {
1618
+ alert("Erro ao identificar os datasets de origem ou destino.");
1617
1619
  return;
1618
1620
  }
1619
- const { parentFileId, ownerId } = parentInfo;
1620
- const specificParentData = JSON.parse(JSON.stringify(graphDataRef.current[parentFileId]));
1621
- specificParentData.nodes.push(newNode);
1622
- specificParentData.links.push(newLink);
1623
- const filenameForSpecificParent = `x_view_dbs/${ownerId}/${parentFileId}`;
1621
+ const isCrossDataset = String(sourceParentInfo.parentFileId) !== String(finalTargetDatasetId);
1622
+ const sourceDataToUpdate = JSON.parse(JSON.stringify(graphDataRef.current[sourceParentInfo.parentFileId]));
1623
+ let targetDataToUpdate = isCrossDataset ? JSON.parse(JSON.stringify(graphDataRef.current[finalTargetDatasetId])) : sourceDataToUpdate;
1624
+ targetDataToUpdate.nodes.push(newNode);
1625
+ sourceDataToUpdate.links.push(newLink);
1626
+ const savePromises = [];
1627
+ if (isCrossDataset) {
1628
+ savePromises.push(
1629
+ actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
1630
+ );
1631
+ savePromises.push(
1632
+ actions.save_view_data(`x_view_dbs/${targetParentInfo.owner_id}/${finalTargetDatasetId}`, targetDataToUpdate)
1633
+ );
1634
+ } else {
1635
+ savePromises.push(
1636
+ actions.save_view_data(`x_view_dbs/${sourceParentInfo.ownerId}/${sourceParentInfo.parentFileId}`, sourceDataToUpdate)
1637
+ );
1638
+ }
1624
1639
  try {
1625
- await context.actions.save_view_data(filenameForSpecificParent, specificParentData);
1626
- graphDataRef.current[parentFileId] = specificParentData;
1640
+ await Promise.all(savePromises);
1641
+ graphDataRef.current[sourceParentInfo.parentFileId] = sourceDataToUpdate;
1642
+ if (isCrossDataset) {
1643
+ graphDataRef.current[finalTargetDatasetId] = targetDataToUpdate;
1644
+ }
1627
1645
  const finalPosition = stateRef.current.ghostElements.node.position.clone();
1628
1646
  addNewNodeToScene(stateRef.current, newNode, newLink, finalPosition);
1647
+ stateRef.current.nodeIdToParentFileMap.set(String(newNode.id), {
1648
+ parentFileId: finalTargetDatasetId,
1649
+ ownerId: targetParentInfo.owner_id,
1650
+ datasetName: targetDataToUpdate.dataset_name || "Dataset Desconhecido"
1651
+ });
1629
1652
  setters.setSceneVersion((v) => v + 1);
1630
1653
  } catch (error) {
1631
1654
  console.error("Falha ao salvar os dados do grafo:", error);
@@ -6765,7 +6788,11 @@ function InSceneCreationForm({
6765
6788
  availableAncestries = [],
6766
6789
  onMentionClick,
6767
6790
  sourceTypes,
6768
- onUploadFile
6791
+ onUploadFile,
6792
+ // Props do Dataset adicionadas
6793
+ availableDatasets = [],
6794
+ sourceNodeDatasetId,
6795
+ viewType
6769
6796
  }) {
6770
6797
  const [name, setName] = useState13("");
6771
6798
  const [types, setTypes] = useState13([]);
@@ -6780,6 +6807,10 @@ function InSceneCreationForm({
6780
6807
  const [isDescriptionModalOpen, setIsDescriptionModalOpen] = useState13(false);
6781
6808
  const [useImageAsTexture, setUseImageAsTexture] = useState13(false);
6782
6809
  const [selectedImageUrl, setSelectedImageUrl] = useState13(null);
6810
+ const [targetDatasetId, setTargetDatasetId] = useState13(sourceNodeDatasetId || "");
6811
+ useEffect13(() => {
6812
+ if (sourceNodeDatasetId) setTargetDatasetId(sourceNodeDatasetId);
6813
+ }, [sourceNodeDatasetId]);
6783
6814
  const propsEndRef = useRef10(null);
6784
6815
  const hasImages = customProps.some((p) => p.type === "images" && Array.isArray(p.value) && p.value.length > 0 && p.value.some((img) => img.value));
6785
6816
  useEffect13(() => {
@@ -6897,6 +6928,8 @@ function InSceneCreationForm({
6897
6928
  description_sections: processedSections,
6898
6929
  useImageAsTexture,
6899
6930
  textureImageUrl: useImageAsTexture ? selectedImageUrl : null,
6931
+ targetDatasetId,
6932
+ // Alvo do Dataset adicionado no onSave
6900
6933
  ...additionalData
6901
6934
  });
6902
6935
  };
@@ -6974,7 +7007,15 @@ function InSceneCreationForm({
6974
7007
  }
6975
7008
  },
6976
7009
  suggestedType
6977
- ))))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ React13.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ React13.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React13.createElement(
7010
+ ))))), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Nome do Node"), /* @__PURE__ */ React13.createElement("input", { required: true, type: "text", placeholder: "Ex.: Cliente XPTO", value: name, onChange: handleNameInputChange, className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60" })), viewType === "view" && availableDatasets.length > 0 && /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Criar Node no Dataset:"), /* @__PURE__ */ React13.createElement(
7011
+ "select",
7012
+ {
7013
+ value: targetDatasetId,
7014
+ onChange: (e) => setTargetDatasetId(e.target.value),
7015
+ className: "w-full bg-slate-800/70 p-2.5 text-sm rounded-lg border border-white/10 focus:outline-none focus:ring-2 focus:ring-indigo-400/60 text-slate-200 cursor-pointer appearance-none"
7016
+ },
7017
+ availableDatasets.map((ds) => /* @__PURE__ */ React13.createElement("option", { key: ds.id, value: ds.id }, ds.name))
7018
+ )), /* @__PURE__ */ React13.createElement("div", { className: "space-y-1.5 relative" }, /* @__PURE__ */ React13.createElement("label", { className: "text-xs text-slate-300" }, "Descri\xE7\xE3o (Opcional)"), /* @__PURE__ */ React13.createElement("div", { className: "relative group min-h-[80px] bg-slate-800/70 p-2.5 rounded-lg border border-white/10 hover:border-white/20 transition-colors" }, /* @__PURE__ */ React13.createElement(
6978
7019
  DescriptionDisplay,
6979
7020
  {
6980
7021
  description,
@@ -7292,7 +7333,7 @@ function InSceneVersionForm({
7292
7333
 
7293
7334
  // src/components/NodeDetailsPanel.jsx
7294
7335
  import React15, { useState as useState15, useEffect as useEffect15, useRef as useRef12 } from "react";
7295
- import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5 } from "react-icons/fi";
7336
+ import { FiPlus as FiPlus5, FiMaximize2 as FiMaximize23, FiX as FiX4, FiCheck as FiCheck9, FiImage as FiImage3, FiEdit2 as FiEdit26, FiLoader as FiLoader2, FiBookOpen as FiBookOpen3, FiSun as FiSun2, FiLink as FiLink5, FiDatabase } from "react-icons/fi";
7296
7337
  function NodeDetailsPanel({
7297
7338
  node,
7298
7339
  onClose,
@@ -7310,7 +7351,9 @@ function NodeDetailsPanel({
7310
7351
  onMentionClick,
7311
7352
  onIntensityChange,
7312
7353
  onUploadFile,
7313
- userRole
7354
+ userRole,
7355
+ currentDatasetName
7356
+ // Prop currentDatasetName adicionada
7314
7357
  }) {
7315
7358
  const [name, setName] = useState15((node == null ? void 0 : node.name) ?? "");
7316
7359
  const [types, setTypes] = useState15([]);
@@ -7721,7 +7764,7 @@ function NodeDetailsPanel({
7721
7764
  onUploadFile: canEdit ? onUploadFile : void 0,
7722
7765
  readOnly: !canEdit
7723
7766
  }
7724
- )), /* @__PURE__ */ React15.createElement("div", { ref: propsEndRef })))), /* @__PURE__ */ React15.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React15.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React15.createElement(
7767
+ )), /* @__PURE__ */ React15.createElement("div", { ref: propsEndRef }))), currentDatasetName && /* @__PURE__ */ React15.createElement("div", { className: "pt-2 mt-4 border-t border-white/10" }, /* @__PURE__ */ React15.createElement("label", { className: "text-[10px] uppercase text-slate-400 font-semibold tracking-wider" }, "Hospedado no Dataset"), /* @__PURE__ */ React15.createElement("div", { className: "flex items-center gap-2 mt-1.5 px-3 py-2 bg-slate-800/40 rounded-lg border border-white/5" }, /* @__PURE__ */ React15.createElement(FiDatabase, { className: "text-indigo-400", size: 14 }), /* @__PURE__ */ React15.createElement("span", { className: "text-xs text-slate-300 truncate font-medium" }, currentDatasetName)))), /* @__PURE__ */ React15.createElement("div", { className: "sticky bottom-0 z-10 bg-gradient-to-t from-slate-950/80 via-slate-950/50 to-transparent px-6 py-4 border-t border-white/10 flex justify-end gap-3" }, /* @__PURE__ */ React15.createElement("button", { onClick: handleCancel, disabled: isSaving, className: "px-4 py-2 rounded-lg border border-white/15 bg-transparent hover:bg-white/5 transition-colors text-sm disabled:opacity-50" }, canEdit ? "Cancelar" : "Fechar"), canEdit && /* @__PURE__ */ React15.createElement(
7725
7768
  "button",
7726
7769
  {
7727
7770
  onClick: () => handleSave(false),
@@ -9055,7 +9098,7 @@ function XViewScene({
9055
9098
  delete_file_action,
9056
9099
  check_user_permission
9057
9100
  }) {
9058
- var _a, _b, _c, _d, _e, _f;
9101
+ var _a, _b, _c, _d, _e, _f, _g;
9059
9102
  const { data: session, status } = useSession();
9060
9103
  const router = useRouter();
9061
9104
  const searchParams = useSearchParams();
@@ -9207,9 +9250,10 @@ function XViewScene({
9207
9250
  const parentFile = allParentData[parentFileId];
9208
9251
  const parentDbInfo = parentDbsArray.find((db) => String(db.db_id) === String(parentFileId));
9209
9252
  const ownerId2 = (parentDbInfo == null ? void 0 : parentDbInfo.owner_id) || null;
9253
+ const datasetName = parentFile.dataset_name || `Dataset #${parentFileId.substring(0, 6)}`;
9210
9254
  if (parentFile.nodes && ownerId2) {
9211
9255
  for (const node of parentFile.nodes) {
9212
- map.set(String(node.id), { parentFileId, ownerId: ownerId2 });
9256
+ map.set(String(node.id), { parentFileId, ownerId: ownerId2, datasetName });
9213
9257
  }
9214
9258
  }
9215
9259
  }
@@ -9729,6 +9773,9 @@ function XViewScene({
9729
9773
  sceneDataRef.current = sceneResponse.data.scene;
9730
9774
  parentDataRef.current = sceneResponse.data.parent;
9731
9775
  ancestryDataRef.current = sceneResponse.data.ancestry;
9776
+ console.log("Console de sceneResponse.data.scene:", sceneResponse.data.scene);
9777
+ console.log("Console de sceneResponse.data.parent:", sceneResponse.data.parent);
9778
+ console.log("Console de sceneResponse.data.ancestry:", sceneResponse.data.ancestry);
9732
9779
  setIsInitialized(true);
9733
9780
  } else {
9734
9781
  console.error("Falha ao buscar dados da cena:", (sceneResponse == null ? void 0 : sceneResponse.error) || "Resposta inv\xE1lida.");
@@ -12055,6 +12102,18 @@ function XViewScene({
12055
12102
  tweenToTarget(nodeMesh, 1.2);
12056
12103
  }
12057
12104
  }, [tweenToTarget]);
12105
+ const availableDatasets = useMemo12(() => {
12106
+ if (!sceneDataRef.current || !parentDataRef.current) return [];
12107
+ return sceneDataRef.current.parent_dbs.map((db) => {
12108
+ var _a2;
12109
+ return {
12110
+ id: db.db_id,
12111
+ name: ((_a2 = parentDataRef.current[db.db_id]) == null ? void 0 : _a2.dataset_name) || `Dataset #${db.db_id.substring(0, 6)}`
12112
+ };
12113
+ });
12114
+ }, [sceneVersion, isInitialized]);
12115
+ const sourceNodeDatasetId = creationMode.sourceNodeData ? (_b = stateRef.current.nodeIdToParentFileMap.get(String(creationMode.sourceNodeData.id))) == null ? void 0 : _b.parentFileId : null;
12116
+ const detailsNodeDatasetInfo = detailsNode ? stateRef.current.nodeIdToParentFileMap.get(String(detailsNode.id)) : null;
12058
12117
  useEffect21(() => {
12059
12118
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
12060
12119
  const nodeObjects = stateRef.current.nodeObjects || {};
@@ -12144,10 +12203,13 @@ function XViewScene({
12144
12203
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12145
12204
  refEl: formRef,
12146
12205
  existingTypes: existingNodeTypes,
12147
- initialColor: (_b = creationMode.sourceNodeData) == null ? void 0 : _b.color,
12148
- sourceTypes: (_c = creationMode.sourceNodeData) == null ? void 0 : _c.type,
12206
+ initialColor: (_c = creationMode.sourceNodeData) == null ? void 0 : _c.color,
12207
+ sourceTypes: (_d = creationMode.sourceNodeData) == null ? void 0 : _d.type,
12149
12208
  onIntensityChange: handleGhostNodeIntensityChange,
12150
- onUploadFile: upload_file_action
12209
+ onUploadFile: upload_file_action,
12210
+ availableDatasets,
12211
+ sourceNodeDatasetId,
12212
+ viewType: viewParams == null ? void 0 : viewParams.type
12151
12213
  }
12152
12214
  ),
12153
12215
  versionMode.isActive && /* @__PURE__ */ React23.createElement(
@@ -12162,8 +12224,8 @@ function XViewScene({
12162
12224
  onMentionClick: handleAddExistingNode,
12163
12225
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12164
12226
  refEl: formRef,
12165
- fixedType: (_d = versionMode.sourceNodeData) == null ? void 0 : _d.type,
12166
- fixedColor: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.color,
12227
+ fixedType: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.type,
12228
+ fixedColor: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.color,
12167
12229
  onUploadFile: upload_file_action
12168
12230
  }
12169
12231
  ),
@@ -12272,7 +12334,8 @@ function XViewScene({
12272
12334
  onMentionClick: handleAddExistingNode,
12273
12335
  onIntensityChange: handleDetailNodeIntensityChange,
12274
12336
  onUploadFile: upload_file_action,
12275
- userRole: userPermissionRole
12337
+ userRole: userPermissionRole,
12338
+ currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
12276
12339
  }
12277
12340
  ),
12278
12341
  detailsLink && /* @__PURE__ */ React23.createElement(
@@ -12400,7 +12463,7 @@ function XViewScene({
12400
12463
  onClose: () => setIsImportModalOpen(false),
12401
12464
  onConfirm: handleConfirmImport,
12402
12465
  session,
12403
- parentDbs: ((_f = sceneDataRef.current) == null ? void 0 : _f.parent_dbs) || [],
12466
+ parentDbs: ((_g = sceneDataRef.current) == null ? void 0 : _g.parent_dbs) || [],
12404
12467
  onFetchAvailableFiles: import_parent_file_modal_get,
12405
12468
  currentViewName: viewParams == null ? void 0 : viewParams.name,
12406
12469
  currentAncestries: ancestryDataRef.current || []
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.2-dev.6",
3
+ "version": "1.2.2-dev.8",
4
4
  "description": "Pacote privado contendo os componentes e lógica de renderização 3D do X View.",
5
5
  "author": "iv.x - Engenharia de Software - ivxsoftwarehouse@gmail.com",
6
6
  "license": "UNLICENSED",