@@ -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