Skip to content

Commit 8315e94

Browse files
authored
ENG-879 A node can have no specification or format (#703)
* eng-879: Error message if neither format nor specification
1 parent 6971bec commit 8315e94

2 files changed

Lines changed: 89 additions & 37 deletions

File tree

apps/roam/src/components/settings/DiscourseNodeSpecification.tsx

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,19 @@ import refreshConfigTree from "~/utils/refreshConfigTree";
88
import getDiscourseNodes from "~/utils/getDiscourseNodes";
99
import getDiscourseNodeFormatExpression from "~/utils/getDiscourseNodeFormatExpression";
1010
import QueryEditor from "~/components/QueryEditor";
11+
import internalError from "~/utils/internalError";
1112

1213
const NodeSpecification = ({
1314
parentUid,
1415
node,
16+
parentSetEnabled,
1517
}: {
1618
parentUid: string;
1719
node: ReturnType<typeof getDiscourseNodes>[number];
20+
parentSetEnabled?: (enabled: boolean) => void;
1821
}) => {
1922
const [migrated, setMigrated] = React.useState(false);
20-
const [enabled, setEnabled] = React.useState(
23+
const [enabled, setEnabled] = React.useState<string>(
2124
() =>
2225
getSubTree({ tree: getBasicTreeByParentUid(parentUid), key: "enabled" })
2326
?.uid,
@@ -66,17 +69,24 @@ const NodeSpecification = ({
6669
},
6770
}),
6871
)
69-
.then(() => setMigrated(true));
72+
.then(() => setMigrated(true))
73+
.catch((error) => {
74+
internalError({ error });
75+
});
7076
}
7177
} else {
7278
const tree = getBasicTreeByParentUid(parentUid);
7379
const scratchNode = getSubTree({ tree, key: "scratch" });
74-
Promise.all(scratchNode.children.map((c) => deleteBlock(c.uid)));
80+
Promise.all(scratchNode.children.map((c) => deleteBlock(c.uid))).catch(
81+
(error) => {
82+
internalError({ error });
83+
},
84+
);
7585
}
7686
return () => {
7787
refreshConfigTree();
7888
};
79-
}, [parentUid, setMigrated, enabled]);
89+
}, [parentUid, setMigrated, enabled, node.format, node.text]);
8090
return (
8191
<div className={"roamjs-node-specification"}>
8292
<style>
@@ -93,9 +103,23 @@ const NodeSpecification = ({
93103
parentUid,
94104
order: 2,
95105
node: { text: "enabled" },
96-
}).then(setEnabled);
106+
})
107+
.then((uid: string) => {
108+
setEnabled(uid);
109+
if (parentSetEnabled) parentSetEnabled(true);
110+
})
111+
.catch((error) => {
112+
internalError({ error });
113+
});
97114
} else {
98-
deleteBlock(enabled).then(() => setEnabled(""));
115+
deleteBlock(enabled)
116+
.then(() => {
117+
setEnabled("");
118+
if (parentSetEnabled) parentSetEnabled(false);
119+
})
120+
.catch((error) => {
121+
internalError({ error });
122+
});
99123
}
100124
}}
101125
/>

apps/roam/src/components/settings/NodeConfig.tsx

Lines changed: 59 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -230,52 +230,73 @@ const NodeConfig = ({
230230
true,
231231
);
232232

233-
const validate = useCallback((tag: string, format: string) => {
234-
const cleanTag = getCleanTagText(tag);
233+
const validate = useCallback(
234+
({
235+
tag,
236+
format,
237+
isSpecificationEnabled,
238+
}: {
239+
tag: string;
240+
format: string;
241+
isSpecificationEnabled?: boolean;
242+
}) => {
243+
if (isSpecificationEnabled === undefined)
244+
isSpecificationEnabled = !!getSubTree({
245+
tree: getBasicTreeByParentUid(specificationUid),
246+
key: "enabled",
247+
})?.uid?.length;
248+
if (format.trim().length === 0 && !isSpecificationEnabled) {
249+
setTagError("");
250+
setFormatError("Error: you must set either a format or specification");
251+
return;
252+
}
253+
const cleanTag = getCleanTagText(tag);
235254

236-
if (!cleanTag) {
237-
setTagError("");
238-
setFormatError("");
239-
return;
240-
}
255+
if (!cleanTag) {
256+
setTagError("");
257+
setFormatError("");
258+
return;
259+
}
241260

242-
const roamTagRegex = /#?\[\[(.*?)\]\]|#(\S+)/g;
243-
const matches = format.matchAll(roamTagRegex);
244-
const formatTags: string[] = [];
245-
for (const match of matches) {
246-
const tagName = match[1] || match[2];
247-
if (tagName) {
248-
formatTags.push(tagName.toUpperCase());
261+
const roamTagRegex = /#?\[\[(.*?)\]\]|#(\S+)/g;
262+
const matches = format.matchAll(roamTagRegex);
263+
const formatTags: string[] = [];
264+
for (const match of matches) {
265+
const tagName = match[1] || match[2];
266+
if (tagName) {
267+
formatTags.push(tagName.toUpperCase());
268+
}
249269
}
250-
}
251270

252-
const hasConflict = formatTags.includes(cleanTag);
271+
const hasConflict = formatTags.includes(cleanTag);
253272

254-
if (hasConflict) {
255-
setFormatError(
256-
`The format references the node's tag "${tag}". Please use a different format or tag.`,
257-
);
258-
setTagError(
259-
`The tag "${tag}" is referenced in the format. Please use a different tag or format.`,
260-
);
261-
} else {
262-
setTagError("");
263-
setFormatError("");
264-
}
265-
}, []);
273+
if (hasConflict) {
274+
setFormatError(
275+
`The format references the node's tag "${tag}". Please use a different format or tag.`,
276+
);
277+
setTagError(
278+
`The tag "${tag}" is referenced in the format. Please use a different tag or format.`,
279+
);
280+
} else {
281+
setTagError("");
282+
setFormatError("");
283+
}
284+
},
285+
[specificationUid],
286+
);
266287

267288
useEffect(() => {
268-
validate(tagValue, formatValue);
289+
validate({ tag: tagValue, format: formatValue });
269290
}, [tagValue, formatValue, validate]);
270291

271292
const handleTagBlur = useCallback(() => {
272293
handleTagBlurFromHook();
273-
validate(tagValue, formatValue);
294+
validate({ tag: tagValue, format: formatValue });
274295
}, [handleTagBlurFromHook, tagValue, formatValue, validate]);
275296

276297
const handleFormatBlur = useCallback(() => {
277298
handleFormatBlurFromHook();
278-
validate(tagValue, formatValue);
299+
validate({ tag: tagValue, format: formatValue });
279300
}, [handleFormatBlurFromHook, tagValue, formatValue, validate]);
280301

281302
return (
@@ -353,6 +374,13 @@ const NodeConfig = ({
353374
<DiscourseNodeSpecification
354375
node={node}
355376
parentUid={specificationUid}
377+
parentSetEnabled={(isSpecificationEnabled) => {
378+
validate({
379+
tag: tagValue,
380+
format: formatValue,
381+
isSpecificationEnabled,
382+
});
383+
}}
356384
/>
357385
</Label>
358386
</div>

0 commit comments

Comments
 (0)