Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion apps/roam/src/components/QueryBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@ type QueryPageComponent = (props: {
pageUid: string;
isEditBlock?: boolean;
showAlias?: boolean;
discourseNodeType?: string;
}) => JSX.Element;

type Props = Parameters<QueryPageComponent>[0];

const QueryBuilder = ({ pageUid, isEditBlock, showAlias }: Props) => {
const QueryBuilder = ({
pageUid,
isEditBlock,
showAlias,
discourseNodeType,
}: Props) => {
const extensionAPI = useExtensionAPI();
const hideMetadata = useMemo(
() =>
Expand Down Expand Up @@ -158,6 +164,7 @@ const QueryBuilder = ({ pageUid, isEditBlock, showAlias }: Props) => {
<>
<QueryEditor
parentUid={pageUid}
discourseNodeType={discourseNodeType}
onQuery={() => {
setHasResults(true);
setIsEdit(false);
Expand Down
37 changes: 37 additions & 0 deletions apps/roam/src/components/QueryEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ import {
import getShallowTreeByParentUid from "roamjs-components/queries/getShallowTreeByParentUid";
import { ALL_SELECTION_SUGGESTIONS } from "~/utils/predefinedSelections";
import { getAlias } from "~/utils/parseResultSettings";
import { setDiscourseNodeSetting } from "~/components/settings/utils/accessors";
import { IndexSchema } from "~/components/settings/utils/zodSchema";

const getSourceCandidates = (cs: Condition[]): string[] =>
cs.flatMap((c) =>
Expand Down Expand Up @@ -434,6 +436,7 @@ type QueryEditorComponent = (props: {
setHasResults?: () => void;
hideCustomSwitch?: boolean;
showAlias?: boolean;
discourseNodeType?: string;
}) => JSX.Element;

const QueryEditor: QueryEditorComponent = ({
Expand All @@ -442,6 +445,7 @@ const QueryEditor: QueryEditorComponent = ({
setHasResults,
hideCustomSwitch,
showAlias,
discourseNodeType,
}) => {
useEffect(() => {
const previewQuery = ((e: CustomEvent) => {
Expand Down Expand Up @@ -476,6 +480,39 @@ const QueryEditor: QueryEditorComponent = ({
const [conditions, _setConditions] = useState(initialConditions);
const [selections, setSelections] = useState(initialSelections);
const [custom, setCustom] = useState(initialCustom);

const blockPropSyncTimeoutRef = useRef(0);
const lastSyncedIndexRef = useRef("");
useEffect(() => {
return () => window.clearTimeout(blockPropSyncTimeoutRef.current);
}, []);
useEffect(() => {
if (!discourseNodeType) return;

const stripped: unknown = JSON.parse(
JSON.stringify({ conditions, selections, custom }, (key, value: unknown) =>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

format with prettier

key === "uid" ? undefined : value,
),
);

const serialized = JSON.stringify(stripped);
if (serialized === lastSyncedIndexRef.current) return;

const result = IndexSchema.safeParse(stripped);
if (!result.success) {
console.error("Index blockprop sync failed validation:", result.error);
return;
}

window.clearTimeout(blockPropSyncTimeoutRef.current);
blockPropSyncTimeoutRef.current = window.setTimeout(() => {
setDiscourseNodeSetting(discourseNodeType, ["index"], result.data);
lastSyncedIndexRef.current = serialized;
}, 250);

return () => window.clearTimeout(blockPropSyncTimeoutRef.current);
}, [conditions, selections, custom, discourseNodeType]);

const customNodeOnChange = (value: string) => {
window.clearTimeout(debounceRef.current);
setCustom(value);
Expand Down
27 changes: 23 additions & 4 deletions apps/roam/src/components/settings/DiscourseNodeIndex.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { DiscourseNode } from "~/utils/getDiscourseNodes";
import QueryBuilder from "~/components/QueryBuilder";
import parseQuery, { DEFAULT_RETURN_NODE } from "~/utils/parseQuery";
import createBlock from "roamjs-components/writes/createBlock";
import { setDiscourseNodeSetting } from "~/components/settings/utils/accessors";

const NodeIndex = ({
parentUid,
Expand All @@ -25,7 +26,7 @@ const NodeIndex = ({
);
useEffect(() => {
if (!showQuery) {
createBlock({
void createBlock({
parentUid: initialQueryArgs.conditionsNodesUid,
node: {
text: "clause",
Expand All @@ -48,12 +49,30 @@ const NodeIndex = ({
},
],
},
}).then(() => setShowQuery(true));
}).then(() => {
setDiscourseNodeSetting(node.type, ["index"], {
conditions: [
{
type: "clause",
source: DEFAULT_RETURN_NODE,
relation: "is a",
target: node.text,
},
],
selections: [],
});

setShowQuery(true);
});
}
}, [parentUid, initialQueryArgs, showQuery]);
}, [parentUid, initialQueryArgs, showQuery, node.text, node.type]);
return (
<ExtensionApiContextProvider {...onloadArgs}>
{showQuery ? <QueryBuilder pageUid={parentUid} /> : <Spinner />}
{showQuery ? (
<QueryBuilder pageUid={parentUid} discourseNodeType={node.type} />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: The pageUid/parentUid is the index block which is a child block of node.type. Seeing as we are passing the parentUid, we can just get the node.type uid based on that, so we don't need to pass it through 2 components.

EG: in Query Editor, where you want to use node.type, use the information that is there to get it (which we know is the ancestor with no parent (or the page uid it is in))

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah never mind, we wouldn't want to make an extra query/check for every query instance

) : (
<Spinner />
)}
</ExtensionApiContextProvider>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ const discourseNodeSettings: DiscourseNodeSettings = {
},
],
selections: [],
custom: "",
},
suggestiveRules,
backedBy: "user",
Expand Down
1 change: 1 addition & 0 deletions apps/roam/src/components/settings/utils/zodSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ export const SelectionSchema = z.object({
export const IndexSchema = z.object({
conditions: z.array(ConditionSchema).default([]),
selections: z.array(SelectionSchema).default([]),
custom: z.string().default(""),
});

type RoamNode = {
Expand Down