@lv-x-software-house/x_view 1.2.2-dev.7 → 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
  }
@@ -12059,6 +12103,18 @@ function XViewScene({
12059
12103
  tweenToTarget(nodeMesh, 1.2);
12060
12104
  }
12061
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;
12062
12118
  (0, import_react23.useEffect)(() => {
12063
12119
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
12064
12120
  const nodeObjects = stateRef.current.nodeObjects || {};
@@ -12148,10 +12204,13 @@ function XViewScene({
12148
12204
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12149
12205
  refEl: formRef,
12150
12206
  existingTypes: existingNodeTypes,
12151
- initialColor: (_b = creationMode.sourceNodeData) == null ? void 0 : _b.color,
12152
- 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,
12153
12209
  onIntensityChange: handleGhostNodeIntensityChange,
12154
- onUploadFile: upload_file_action
12210
+ onUploadFile: upload_file_action,
12211
+ availableDatasets,
12212
+ sourceNodeDatasetId,
12213
+ viewType: viewParams == null ? void 0 : viewParams.type
12155
12214
  }
12156
12215
  ),
12157
12216
  versionMode.isActive && /* @__PURE__ */ import_react23.default.createElement(
@@ -12166,8 +12225,8 @@ function XViewScene({
12166
12225
  onMentionClick: handleAddExistingNode,
12167
12226
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12168
12227
  refEl: formRef,
12169
- fixedType: (_d = versionMode.sourceNodeData) == null ? void 0 : _d.type,
12170
- 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,
12171
12230
  onUploadFile: upload_file_action
12172
12231
  }
12173
12232
  ),
@@ -12276,7 +12335,8 @@ function XViewScene({
12276
12335
  onMentionClick: handleAddExistingNode,
12277
12336
  onIntensityChange: handleDetailNodeIntensityChange,
12278
12337
  onUploadFile: upload_file_action,
12279
- userRole: userPermissionRole
12338
+ userRole: userPermissionRole,
12339
+ currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
12280
12340
  }
12281
12341
  ),
12282
12342
  detailsLink && /* @__PURE__ */ import_react23.default.createElement(
@@ -12404,7 +12464,7 @@ function XViewScene({
12404
12464
  onClose: () => setIsImportModalOpen(false),
12405
12465
  onConfirm: handleConfirmImport,
12406
12466
  session,
12407
- parentDbs: ((_f = sceneDataRef.current) == null ? void 0 : _f.parent_dbs) || [],
12467
+ parentDbs: ((_g = sceneDataRef.current) == null ? void 0 : _g.parent_dbs) || [],
12408
12468
  onFetchAvailableFiles: import_parent_file_modal_get,
12409
12469
  currentViewName: viewParams == null ? void 0 : viewParams.name,
12410
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
  }
@@ -12058,6 +12102,18 @@ function XViewScene({
12058
12102
  tweenToTarget(nodeMesh, 1.2);
12059
12103
  }
12060
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;
12061
12117
  useEffect21(() => {
12062
12118
  if (isInitialized && focusNodeId && !hasFocusedInitial) {
12063
12119
  const nodeObjects = stateRef.current.nodeObjects || {};
@@ -12147,10 +12203,13 @@ function XViewScene({
12147
12203
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12148
12204
  refEl: formRef,
12149
12205
  existingTypes: existingNodeTypes,
12150
- initialColor: (_b = creationMode.sourceNodeData) == null ? void 0 : _b.color,
12151
- 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,
12152
12208
  onIntensityChange: handleGhostNodeIntensityChange,
12153
- onUploadFile: upload_file_action
12209
+ onUploadFile: upload_file_action,
12210
+ availableDatasets,
12211
+ sourceNodeDatasetId,
12212
+ viewType: viewParams == null ? void 0 : viewParams.type
12154
12213
  }
12155
12214
  ),
12156
12215
  versionMode.isActive && /* @__PURE__ */ React23.createElement(
@@ -12165,8 +12224,8 @@ function XViewScene({
12165
12224
  onMentionClick: handleAddExistingNode,
12166
12225
  style: { position: "absolute", left: `${formPosition.left}px`, top: `${formPosition.top}px`, opacity: formPosition.opacity, zIndex: 20, transition: "opacity 200ms ease-out" },
12167
12226
  refEl: formRef,
12168
- fixedType: (_d = versionMode.sourceNodeData) == null ? void 0 : _d.type,
12169
- 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,
12170
12229
  onUploadFile: upload_file_action
12171
12230
  }
12172
12231
  ),
@@ -12275,7 +12334,8 @@ function XViewScene({
12275
12334
  onMentionClick: handleAddExistingNode,
12276
12335
  onIntensityChange: handleDetailNodeIntensityChange,
12277
12336
  onUploadFile: upload_file_action,
12278
- userRole: userPermissionRole
12337
+ userRole: userPermissionRole,
12338
+ currentDatasetName: detailsNodeDatasetInfo == null ? void 0 : detailsNodeDatasetInfo.datasetName
12279
12339
  }
12280
12340
  ),
12281
12341
  detailsLink && /* @__PURE__ */ React23.createElement(
@@ -12403,7 +12463,7 @@ function XViewScene({
12403
12463
  onClose: () => setIsImportModalOpen(false),
12404
12464
  onConfirm: handleConfirmImport,
12405
12465
  session,
12406
- parentDbs: ((_f = sceneDataRef.current) == null ? void 0 : _f.parent_dbs) || [],
12466
+ parentDbs: ((_g = sceneDataRef.current) == null ? void 0 : _g.parent_dbs) || [],
12407
12467
  onFetchAvailableFiles: import_parent_file_modal_get,
12408
12468
  currentViewName: viewParams == null ? void 0 : viewParams.name,
12409
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.7",
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",