Skip to content

Commit ce51bc3

Browse files
authored
ENG-1300 Publish relations when a node is published (#827)
1 parent 4d43317 commit ce51bc3

11 files changed

Lines changed: 323 additions & 81 deletions

File tree

apps/obsidian/src/components/ImportNodesModal.tsx

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { StrictMode, useState, useEffect, useCallback } from "react";
44
import type DiscourseGraphPlugin from "../index";
55
import type { ImportableNode, GroupWithNodes } from "~/types";
66
import {
7-
getAvailableGroups,
7+
getAvailableGroupIds,
88
getPublishedNodesForGroups,
99
getLocalNodeInstanceIds,
1010
getSpaceNameFromIds,
@@ -45,15 +45,13 @@ const ImportNodesContent = ({ plugin, onClose }: ImportNodesModalProps) => {
4545
return;
4646
}
4747

48-
const groups = await getAvailableGroups(client);
49-
if (groups.length === 0) {
48+
const groupIds = await getAvailableGroupIds(client);
49+
if (groupIds.length === 0) {
5050
new Notice("You are not a member of any groups");
5151
onClose();
5252
return;
5353
}
5454

55-
const groupIds = groups.map((g) => g.group_id);
56-
5755
const publishedNodes = await getPublishedNodesForGroups({
5856
client,
5957
groupIds,

apps/obsidian/src/components/RelationshipSection.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ const CurrentRelationships = ({
402402

403403
const group = tempRelationships.get(relationKey)!;
404404
const otherId = isSource ? r.destination : r.source;
405-
const linkedFile = await getFileForNodeInstanceId(plugin, otherId);
405+
const linkedFile = getFileForNodeInstanceId(plugin, otherId);
406406
if (
407407
linkedFile &&
408408
!group.linkedFiles.some((f) => f.path === linkedFile.path)

apps/obsidian/src/components/canvas/overlays/RelationPanel.tsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,7 @@ const computeRelations = async (
540540
const nodeInstanceId = await getNodeInstanceIdForFile(plugin, file);
541541
if (!nodeInstanceId) return [];
542542

543-
const relations = await getRelationsForNodeInstanceId(
544-
plugin,
545-
nodeInstanceId,
546-
);
543+
const relations = await getRelationsForNodeInstanceId(plugin, nodeInstanceId);
547544
const result = new Map<string, GroupedRelation>();
548545

549546
for (const relationType of plugin.settings.relationTypes) {
@@ -573,7 +570,7 @@ const computeRelations = async (
573570
const group = result.get(key)!;
574571
for (const r of instanceRels) {
575572
const otherId = r.source === nodeInstanceId ? r.destination : r.source;
576-
const linked = await getFileForNodeInstanceId(plugin, otherId);
573+
const linked = getFileForNodeInstanceId(plugin, otherId);
577574
if (linked && !group.linkedFiles.some((f) => f.path === linked.path)) {
578575
group.linkedFiles.push(linked);
579576
}

apps/obsidian/src/services/QueryEngine.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ export class QueryEngine {
3737
this.app = app;
3838
}
3939

40+
functional = () => !!this.dc;
41+
4042
/**
4143
* Search across all discourse nodes (files that have frontmatter nodeTypeId)
4244
*/
@@ -81,6 +83,33 @@ export class QueryEngine {
8183
}
8284
};
8385

86+
/**
87+
* Search across all discourse nodes that have nodeInstanceId
88+
*/
89+
getDiscourseNodeById = (nodeInstanceId: string): TFile | null => {
90+
if (!this.dc) {
91+
console.warn(
92+
"Datacore API not available. Search functionality is not available.",
93+
);
94+
return null;
95+
}
96+
97+
if (!nodeInstanceId.match(/^[-.+\w]+$/)) {
98+
console.error("Malformed id:", nodeInstanceId);
99+
return null;
100+
}
101+
try {
102+
const dcQuery = `@page and exists(nodeInstanceId) and nodeInstanceId = "${nodeInstanceId}"`;
103+
const potentialNodes = this.dc.query(dcQuery);
104+
const path = potentialNodes.at(0)?.$path;
105+
if (!path) return null;
106+
return this.app.vault.getFileByPath(path);
107+
} catch (error) {
108+
console.error("Error in searchDiscourseNodeById:", error);
109+
return null;
110+
}
111+
};
112+
84113
searchCompatibleNodeByTitle = async ({
85114
query,
86115
compatibleNodeTypeIds,

apps/obsidian/src/utils/conceptConversion.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,8 @@ const orderConceptsRec = ({
288288
remainder: { [key: string]: LocalConceptDataInput };
289289
processed: Set<string>;
290290
}): Set<string> => {
291+
// Add to processed at the start to prevent cycles
292+
processed.add(concept.source_local_id!);
291293
const relatedConceptIds = relatedConcepts(concept);
292294
let missing: Set<string> = new Set();
293295
while (relatedConceptIds.length > 0) {
@@ -310,7 +312,6 @@ const orderConceptsRec = ({
310312
}
311313
}
312314
ordered.push(concept);
313-
processed.add(concept.source_local_id!);
314315
delete remainder[concept.source_local_id!];
315316
return missing;
316317
};

apps/obsidian/src/utils/importNodes.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import type { DiscourseNode, ImportableNode } from "~/types";
99
import { QueryEngine } from "~/services/QueryEngine";
1010
import { spaceUriAndLocalIdToRid, ridToSpaceUriAndLocalId } from "./rid";
1111

12-
export const getAvailableGroups = async (
12+
export const getAvailableGroupIds = async (
1313
client: DGSupabaseClient,
14-
): Promise<{ group_id: string }[]> => {
14+
): Promise<string[]> => {
1515
const { data, error } = await client
1616
.from("group_membership")
1717
.select("group_id")
@@ -22,7 +22,7 @@ export const getAvailableGroups = async (
2222
throw new Error(`Failed to fetch groups: ${error.message}`);
2323
}
2424

25-
return data || [];
25+
return (data || []).map((g) => g.group_id);
2626
};
2727

2828
export const getPublishedNodesForGroups = async ({

0 commit comments

Comments
 (0)