@lv-x-software-house/x_view 1.2.3-dev.5 → 1.2.3-dev.7

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
@@ -96,6 +96,17 @@ function defineAbilityFor(role) {
96
96
  cannot("manage", "AncestryBoard");
97
97
  cannot("update", "Node");
98
98
  break;
99
+ case "link_viewer":
100
+ can("read", "Node");
101
+ can("read", "Ancestry");
102
+ can("read", "Versioning");
103
+ cannot("read", "Scene");
104
+ cannot("read", "Connection");
105
+ cannot("read", "AncestryBoard");
106
+ cannot("read", "AncestryGroup");
107
+ cannot("dismiss", "Node");
108
+ cannot("manage", "all");
109
+ break;
99
110
  default:
100
111
  can("read", "Connection");
101
112
  can("dismiss", "Node");
@@ -9675,11 +9686,14 @@ function XViewScene({
9675
9686
  const { id, type, owner_id } = viewParams;
9676
9687
  try {
9677
9688
  const result = await check_user_permission(owner_id, type, id, session);
9689
+ const hasDirectLinkTarget = !!(focusNodeId || focusAncestryId);
9678
9690
  if (result.success && result.isValidMember) {
9679
9691
  setUserPermissionRole(result.permission);
9680
9692
  setPermissionStatus("granted");
9693
+ } else if (hasDirectLinkTarget) {
9694
+ setUserPermissionRole("link_viewer");
9695
+ setPermissionStatus("granted");
9681
9696
  } else {
9682
- console.warn("\u26D4 Acesso negado: Usu\xE1rio n\xE3o \xE9 membro deste card.");
9683
9697
  setPermissionStatus("denied");
9684
9698
  setIsLoading(false);
9685
9699
  }
@@ -10309,7 +10323,7 @@ function XViewScene({
10309
10323
  try {
10310
10324
  const typeStr = (viewParams == null ? void 0 : viewParams.type) || "";
10311
10325
  const sceneType = typeStr.toLowerCase().includes("database") ? "database" : "view";
10312
- const scenePromise = get_scene_view_data(configPath, ownerId2);
10326
+ const scenePromise = get_scene_view_data(configPath, ownerId2, typeStr, session, focusNodeId, focusAncestryId);
10313
10327
  const boardPromise = get_ancestry_board_action && session ? get_ancestry_board_action(configPath, sceneType, session, ownerId2) : Promise.resolve({ success: false, data: [] });
10314
10328
  const [sceneResponse, boardResponse] = await Promise.all([scenePromise, boardPromise]);
10315
10329
  if ((sceneResponse == null ? void 0 : sceneResponse.success) && ((_a2 = sceneResponse.data) == null ? void 0 : _a2.scene) && ((_b2 = sceneResponse.data) == null ? void 0 : _b2.parent)) {
@@ -12723,7 +12737,7 @@ function XViewScene({
12723
12737
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
12724
12738
  }
12725
12739
  },
12726
- /* @__PURE__ */ import_react24.default.createElement(
12740
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ import_react24.default.createElement(
12727
12741
  XViewSidebar,
12728
12742
  {
12729
12743
  dbNodes: searchableDbNodes,
@@ -12763,7 +12777,9 @@ function XViewScene({
12763
12777
  onUploadFile: upload_file_action,
12764
12778
  availableDatasets,
12765
12779
  sourceNodeDatasetId,
12766
- viewType: viewParams == null ? void 0 : viewParams.type
12780
+ viewType: viewParams == null ? void 0 : viewParams.type,
12781
+ availableNodes: allAvailableNodes,
12782
+ availableAncestries: allAvailableAncestries
12767
12783
  }
12768
12784
  ),
12769
12785
  versionMode.isActive && /* @__PURE__ */ import_react24.default.createElement(
@@ -12780,7 +12796,9 @@ function XViewScene({
12780
12796
  refEl: formRef,
12781
12797
  fixedType: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.type,
12782
12798
  fixedColor: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.color,
12783
- onUploadFile: upload_file_action
12799
+ onUploadFile: upload_file_action,
12800
+ availableNodes: allAvailableNodes,
12801
+ availableAncestries: allAvailableAncestries
12784
12802
  }
12785
12803
  ),
12786
12804
  readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ import_react24.default.createElement(
@@ -13047,9 +13065,17 @@ async function save_view_data_logic(db_services, filename, data) {
13047
13065
  return { success: false, error: error.message };
13048
13066
  }
13049
13067
  }
13050
- async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13051
- var _a, _b;
13068
+ async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
13069
+ var _a, _b, _c;
13052
13070
  try {
13071
+ if (!session || !session.user) {
13072
+ return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
13073
+ }
13074
+ const membershipCheck = await db_services.check_membership(owner_id, type, scene_config, session.user.id);
13075
+ const isFullMember = membershipCheck.success && membershipCheck.isValidMember;
13076
+ if (!isFullMember && !focusNodeId && !focusAncestryId) {
13077
+ return { success: false, error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio." };
13078
+ }
13053
13079
  const sceneResponse = await db_services.get_file(`x_view_scenes/${owner_id}/${scene_config}`);
13054
13080
  if (!sceneResponse || !sceneResponse.success) {
13055
13081
  console.error("Falha ao buscar dados da cena:", sceneResponse == null ? void 0 : sceneResponse.error);
@@ -13138,8 +13164,7 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13138
13164
  ancestryData.forEach((anc) => {
13139
13165
  const targetSourceId = anc._source_file_id || anc._imported_from_view_id;
13140
13166
  const targetOwnerId = anc._source_owner_id || anc._imported_from_view_owner_id;
13141
- if (targetSourceId && targetSourceId !== scene_config && // Não é o arquivo atual
13142
- targetOwnerId) {
13167
+ if (targetSourceId && targetSourceId !== scene_config && targetOwnerId) {
13143
13168
  const isAlreadyLoadedAsParent = parentDbObjects.some((db) => String(db.db_id) === String(targetSourceId));
13144
13169
  if (!isAlreadyLoadedAsParent) {
13145
13170
  const key = `${targetOwnerId}/${targetSourceId}`;
@@ -13170,7 +13195,6 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13170
13195
  });
13171
13196
  } else if (result.status === "fulfilled" && !((_b2 = result.value) == null ? void 0 : _b2.success)) {
13172
13197
  failedSources.add(result.value._meta_key);
13173
- } else if (result.status === "rejected") {
13174
13198
  }
13175
13199
  });
13176
13200
  ancestryData = ancestryData.filter((localAnc) => {
@@ -13239,7 +13263,6 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13239
13263
  ...ancestry,
13240
13264
  tree: cleanedTree,
13241
13265
  abstraction_tree: cleanedAbstraction
13242
- // Salva a árvore limpa
13243
13266
  };
13244
13267
  }).filter(Boolean);
13245
13268
  if (JSON.stringify(cleanedAncestryData) !== originalAncestryDataString) {
@@ -13250,16 +13273,63 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13250
13273
  console.error("Falha ao salvar o arquivo de ancestralidade da cena atualizado:", saveError);
13251
13274
  }
13252
13275
  }
13276
+ if (!isFullMember) {
13277
+ let restrictedParentData = {};
13278
+ let restrictedSceneData = { ...validatedSceneData, nodes: [], links: [] };
13279
+ let restrictedAncestryData = [];
13280
+ if (focusNodeId) {
13281
+ const allNodes2 = Object.values(parentData).flatMap((db) => db.nodes || []);
13282
+ const targetNode = allNodes2.find((n) => String(n.id) === String(focusNodeId));
13283
+ if (!targetNode) return { success: false, error: "Node n\xE3o encontrado." };
13284
+ for (const [dbId, dbContent] of Object.entries(parentData)) {
13285
+ const nodeInDb = (_c = dbContent.nodes) == null ? void 0 : _c.find((n) => String(n.id) === String(focusNodeId));
13286
+ if (nodeInDb) {
13287
+ restrictedParentData[dbId] = { ...dbContent, nodes: [nodeInDb], links: [] };
13288
+ break;
13289
+ }
13290
+ }
13291
+ restrictedSceneData.nodes = [targetNode];
13292
+ } else if (focusAncestryId) {
13293
+ const targetAncestry = ancestryData.find((a) => String(a.ancestry_id) === String(focusAncestryId));
13294
+ if (!targetAncestry || targetAncestry.is_private) {
13295
+ return { success: false, error: "Ancestralidade n\xE3o encontrada ou \xE9 privada." };
13296
+ }
13297
+ const requiredNodeIds = /* @__PURE__ */ new Set();
13298
+ const requiredAncestryIds = /* @__PURE__ */ new Set([String(focusAncestryId)]);
13299
+ const extractDependencies = (treeItem) => {
13300
+ var _a2;
13301
+ if (!treeItem) return;
13302
+ if (treeItem.node_id) requiredNodeIds.add(String(treeItem.node_id));
13303
+ if ((_a2 = treeItem.node) == null ? void 0 : _a2.id) requiredNodeIds.add(String(treeItem.node.id));
13304
+ if (treeItem.children) treeItem.children.forEach(extractDependencies);
13305
+ if (treeItem.parallel_branches) {
13306
+ treeItem.parallel_branches.forEach((branch) => {
13307
+ if (branch.linked_ancestry_id) requiredAncestryIds.add(String(branch.linked_ancestry_id));
13308
+ extractDependencies(branch.tree);
13309
+ });
13310
+ }
13311
+ };
13312
+ extractDependencies(targetAncestry.tree);
13313
+ extractDependencies(targetAncestry.abstraction_tree);
13314
+ restrictedAncestryData = ancestryData.filter((a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private);
13315
+ for (const [dbId, dbContent] of Object.entries(parentData)) {
13316
+ const filteredNodes = (dbContent.nodes || []).filter((n) => requiredNodeIds.has(String(n.id)));
13317
+ if (filteredNodes.length > 0) {
13318
+ restrictedParentData[dbId] = { ...dbContent, nodes: filteredNodes, links: [] };
13319
+ }
13320
+ }
13321
+ }
13322
+ return {
13323
+ success: true,
13324
+ data: { scene: restrictedSceneData, parent: restrictedParentData, ancestry: restrictedAncestryData }
13325
+ };
13326
+ }
13253
13327
  return {
13254
13328
  success: true,
13255
- data: {
13256
- scene: validatedSceneData,
13257
- parent: parentData,
13258
- ancestry: ancestryData
13259
- }
13329
+ data: { scene: validatedSceneData, parent: parentData, ancestry: ancestryData }
13260
13330
  };
13261
13331
  } catch (error) {
13262
- console.error("catch (error) em get_scene_view_data_logic:", error);
13332
+ console.error("Erro em get_scene_view_data_logic:", error);
13263
13333
  return { success: false, error: error.message };
13264
13334
  }
13265
13335
  }
package/dist/index.mjs CHANGED
@@ -52,6 +52,17 @@ function defineAbilityFor(role) {
52
52
  cannot("manage", "AncestryBoard");
53
53
  cannot("update", "Node");
54
54
  break;
55
+ case "link_viewer":
56
+ can("read", "Node");
57
+ can("read", "Ancestry");
58
+ can("read", "Versioning");
59
+ cannot("read", "Scene");
60
+ cannot("read", "Connection");
61
+ cannot("read", "AncestryBoard");
62
+ cannot("read", "AncestryGroup");
63
+ cannot("dismiss", "Node");
64
+ cannot("manage", "all");
65
+ break;
55
66
  default:
56
67
  can("read", "Connection");
57
68
  can("dismiss", "Node");
@@ -9675,11 +9686,14 @@ function XViewScene({
9675
9686
  const { id, type, owner_id } = viewParams;
9676
9687
  try {
9677
9688
  const result = await check_user_permission(owner_id, type, id, session);
9689
+ const hasDirectLinkTarget = !!(focusNodeId || focusAncestryId);
9678
9690
  if (result.success && result.isValidMember) {
9679
9691
  setUserPermissionRole(result.permission);
9680
9692
  setPermissionStatus("granted");
9693
+ } else if (hasDirectLinkTarget) {
9694
+ setUserPermissionRole("link_viewer");
9695
+ setPermissionStatus("granted");
9681
9696
  } else {
9682
- console.warn("\u26D4 Acesso negado: Usu\xE1rio n\xE3o \xE9 membro deste card.");
9683
9697
  setPermissionStatus("denied");
9684
9698
  setIsLoading(false);
9685
9699
  }
@@ -10309,7 +10323,7 @@ function XViewScene({
10309
10323
  try {
10310
10324
  const typeStr = (viewParams == null ? void 0 : viewParams.type) || "";
10311
10325
  const sceneType = typeStr.toLowerCase().includes("database") ? "database" : "view";
10312
- const scenePromise = get_scene_view_data(configPath, ownerId2);
10326
+ const scenePromise = get_scene_view_data(configPath, ownerId2, typeStr, session, focusNodeId, focusAncestryId);
10313
10327
  const boardPromise = get_ancestry_board_action && session ? get_ancestry_board_action(configPath, sceneType, session, ownerId2) : Promise.resolve({ success: false, data: [] });
10314
10328
  const [sceneResponse, boardResponse] = await Promise.all([scenePromise, boardPromise]);
10315
10329
  if ((sceneResponse == null ? void 0 : sceneResponse.success) && ((_a2 = sceneResponse.data) == null ? void 0 : _a2.scene) && ((_b2 = sceneResponse.data) == null ? void 0 : _b2.parent)) {
@@ -12723,7 +12737,7 @@ function XViewScene({
12723
12737
  cursor: stateRef.current.connection.isActive || stateRef.current.relink.isActive || ancestryMode.isActive ? "crosshair" : creationMode.isActive ? "default" : "grab"
12724
12738
  }
12725
12739
  },
12726
- /* @__PURE__ */ React23.createElement(
12740
+ userPermissionRole !== "link_viewer" && /* @__PURE__ */ React23.createElement(
12727
12741
  XViewSidebar,
12728
12742
  {
12729
12743
  dbNodes: searchableDbNodes,
@@ -12763,7 +12777,9 @@ function XViewScene({
12763
12777
  onUploadFile: upload_file_action,
12764
12778
  availableDatasets,
12765
12779
  sourceNodeDatasetId,
12766
- viewType: viewParams == null ? void 0 : viewParams.type
12780
+ viewType: viewParams == null ? void 0 : viewParams.type,
12781
+ availableNodes: allAvailableNodes,
12782
+ availableAncestries: allAvailableAncestries
12767
12783
  }
12768
12784
  ),
12769
12785
  versionMode.isActive && /* @__PURE__ */ React23.createElement(
@@ -12780,7 +12796,9 @@ function XViewScene({
12780
12796
  refEl: formRef,
12781
12797
  fixedType: (_e = versionMode.sourceNodeData) == null ? void 0 : _e.type,
12782
12798
  fixedColor: (_f = versionMode.sourceNodeData) == null ? void 0 : _f.color,
12783
- onUploadFile: upload_file_action
12799
+ onUploadFile: upload_file_action,
12800
+ availableNodes: allAvailableNodes,
12801
+ availableAncestries: allAvailableAncestries
12784
12802
  }
12785
12803
  ),
12786
12804
  readingMode.isActive && readingMode.ancestry && /* @__PURE__ */ React23.createElement(
@@ -13047,9 +13065,17 @@ async function save_view_data_logic(db_services, filename, data) {
13047
13065
  return { success: false, error: error.message };
13048
13066
  }
13049
13067
  }
13050
- async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13051
- var _a, _b;
13068
+ async function get_scene_view_data_logic(db_services, scene_config, owner_id, type, session, focusNodeId = null, focusAncestryId = null) {
13069
+ var _a, _b, _c;
13052
13070
  try {
13071
+ if (!session || !session.user) {
13072
+ return { success: false, error: "Usu\xE1rio n\xE3o autenticado." };
13073
+ }
13074
+ const membershipCheck = await db_services.check_membership(owner_id, type, scene_config, session.user.id);
13075
+ const isFullMember = membershipCheck.success && membershipCheck.isValidMember;
13076
+ if (!isFullMember && !focusNodeId && !focusAncestryId) {
13077
+ return { success: false, error: "Acesso Negado: Voc\xEA n\xE3o possui permiss\xE3o para acessar este cen\xE1rio." };
13078
+ }
13053
13079
  const sceneResponse = await db_services.get_file(`x_view_scenes/${owner_id}/${scene_config}`);
13054
13080
  if (!sceneResponse || !sceneResponse.success) {
13055
13081
  console.error("Falha ao buscar dados da cena:", sceneResponse == null ? void 0 : sceneResponse.error);
@@ -13138,8 +13164,7 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13138
13164
  ancestryData.forEach((anc) => {
13139
13165
  const targetSourceId = anc._source_file_id || anc._imported_from_view_id;
13140
13166
  const targetOwnerId = anc._source_owner_id || anc._imported_from_view_owner_id;
13141
- if (targetSourceId && targetSourceId !== scene_config && // Não é o arquivo atual
13142
- targetOwnerId) {
13167
+ if (targetSourceId && targetSourceId !== scene_config && targetOwnerId) {
13143
13168
  const isAlreadyLoadedAsParent = parentDbObjects.some((db) => String(db.db_id) === String(targetSourceId));
13144
13169
  if (!isAlreadyLoadedAsParent) {
13145
13170
  const key = `${targetOwnerId}/${targetSourceId}`;
@@ -13170,7 +13195,6 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13170
13195
  });
13171
13196
  } else if (result.status === "fulfilled" && !((_b2 = result.value) == null ? void 0 : _b2.success)) {
13172
13197
  failedSources.add(result.value._meta_key);
13173
- } else if (result.status === "rejected") {
13174
13198
  }
13175
13199
  });
13176
13200
  ancestryData = ancestryData.filter((localAnc) => {
@@ -13239,7 +13263,6 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13239
13263
  ...ancestry,
13240
13264
  tree: cleanedTree,
13241
13265
  abstraction_tree: cleanedAbstraction
13242
- // Salva a árvore limpa
13243
13266
  };
13244
13267
  }).filter(Boolean);
13245
13268
  if (JSON.stringify(cleanedAncestryData) !== originalAncestryDataString) {
@@ -13250,16 +13273,63 @@ async function get_scene_view_data_logic(db_services, scene_config, owner_id) {
13250
13273
  console.error("Falha ao salvar o arquivo de ancestralidade da cena atualizado:", saveError);
13251
13274
  }
13252
13275
  }
13276
+ if (!isFullMember) {
13277
+ let restrictedParentData = {};
13278
+ let restrictedSceneData = { ...validatedSceneData, nodes: [], links: [] };
13279
+ let restrictedAncestryData = [];
13280
+ if (focusNodeId) {
13281
+ const allNodes2 = Object.values(parentData).flatMap((db) => db.nodes || []);
13282
+ const targetNode = allNodes2.find((n) => String(n.id) === String(focusNodeId));
13283
+ if (!targetNode) return { success: false, error: "Node n\xE3o encontrado." };
13284
+ for (const [dbId, dbContent] of Object.entries(parentData)) {
13285
+ const nodeInDb = (_c = dbContent.nodes) == null ? void 0 : _c.find((n) => String(n.id) === String(focusNodeId));
13286
+ if (nodeInDb) {
13287
+ restrictedParentData[dbId] = { ...dbContent, nodes: [nodeInDb], links: [] };
13288
+ break;
13289
+ }
13290
+ }
13291
+ restrictedSceneData.nodes = [targetNode];
13292
+ } else if (focusAncestryId) {
13293
+ const targetAncestry = ancestryData.find((a) => String(a.ancestry_id) === String(focusAncestryId));
13294
+ if (!targetAncestry || targetAncestry.is_private) {
13295
+ return { success: false, error: "Ancestralidade n\xE3o encontrada ou \xE9 privada." };
13296
+ }
13297
+ const requiredNodeIds = /* @__PURE__ */ new Set();
13298
+ const requiredAncestryIds = /* @__PURE__ */ new Set([String(focusAncestryId)]);
13299
+ const extractDependencies = (treeItem) => {
13300
+ var _a2;
13301
+ if (!treeItem) return;
13302
+ if (treeItem.node_id) requiredNodeIds.add(String(treeItem.node_id));
13303
+ if ((_a2 = treeItem.node) == null ? void 0 : _a2.id) requiredNodeIds.add(String(treeItem.node.id));
13304
+ if (treeItem.children) treeItem.children.forEach(extractDependencies);
13305
+ if (treeItem.parallel_branches) {
13306
+ treeItem.parallel_branches.forEach((branch) => {
13307
+ if (branch.linked_ancestry_id) requiredAncestryIds.add(String(branch.linked_ancestry_id));
13308
+ extractDependencies(branch.tree);
13309
+ });
13310
+ }
13311
+ };
13312
+ extractDependencies(targetAncestry.tree);
13313
+ extractDependencies(targetAncestry.abstraction_tree);
13314
+ restrictedAncestryData = ancestryData.filter((a) => requiredAncestryIds.has(String(a.ancestry_id)) && !a.is_private);
13315
+ for (const [dbId, dbContent] of Object.entries(parentData)) {
13316
+ const filteredNodes = (dbContent.nodes || []).filter((n) => requiredNodeIds.has(String(n.id)));
13317
+ if (filteredNodes.length > 0) {
13318
+ restrictedParentData[dbId] = { ...dbContent, nodes: filteredNodes, links: [] };
13319
+ }
13320
+ }
13321
+ }
13322
+ return {
13323
+ success: true,
13324
+ data: { scene: restrictedSceneData, parent: restrictedParentData, ancestry: restrictedAncestryData }
13325
+ };
13326
+ }
13253
13327
  return {
13254
13328
  success: true,
13255
- data: {
13256
- scene: validatedSceneData,
13257
- parent: parentData,
13258
- ancestry: ancestryData
13259
- }
13329
+ data: { scene: validatedSceneData, parent: parentData, ancestry: ancestryData }
13260
13330
  };
13261
13331
  } catch (error) {
13262
- console.error("catch (error) em get_scene_view_data_logic:", error);
13332
+ console.error("Erro em get_scene_view_data_logic:", error);
13263
13333
  return { success: false, error: error.message };
13264
13334
  }
13265
13335
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lv-x-software-house/x_view",
3
- "version": "1.2.3-dev.5",
3
+ "version": "1.2.3-dev.7",
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",