Skip to content

Commit 0d8a84d

Browse files
authored
feat(dashboard): repeat/digest can't be nested inside another repeat (#8136)
1 parent ce85343 commit 0d8a84d

File tree

5 files changed

+114
-74
lines changed

5 files changed

+114
-74
lines changed

apps/dashboard/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
"@hookform/resolvers": "^3.9.0",
2626
"@lezer/highlight": "^1.2.1",
2727
"@maily-to/core": "github:novuhq/maily.to.git#release/v0.2.7-novu.6-core&path:/packages/core",
28-
"@maily-to/core-digest": "github:novuhq/maily.to.git#release/v0.2.7-novu.8-core&path:/packages/core",
28+
"@maily-to/core-digest": "github:novuhq/maily.to.git#release/v0.2.7-novu.9-core&path:/packages/core",
2929
"@novu/api": "workspace:*",
3030
"@novu/framework": "workspace:*",
3131
"@novu/js": "workspace:*",

apps/dashboard/src/components/workflow-editor/steps/email/maily-config.tsx

+38-4
Original file line numberDiff line numberDiff line change
@@ -22,23 +22,32 @@ import {
2222
text,
2323
} from '@maily-to/core/blocks';
2424
import {
25+
getSlashCommandSuggestions,
2526
getVariableSuggestions,
2627
HTMLCodeBlockExtension,
2728
RepeatExtension,
29+
SlashCommandExtension,
2830
VariableExtension,
2931
Variables,
3032
} from '@maily-to/core/extensions';
3133
import { ReactNodeViewRenderer } from '@tiptap/react';
34+
import { searchSlashCommands } from '@maily-to/core-digest/extensions';
35+
import { StepResponseDto } from '@novu/shared';
36+
import { createDigestBlock } from './blocks/digest';
37+
import {
38+
CalculateVariablesProps,
39+
insertVariableToEditor,
40+
isInsideRepeatBlock,
41+
VariableFrom,
42+
} from './variables/variables';
3243
import { ForView } from './views/for-view';
3344
import { createVariableView } from './views/variable-view';
3445
import { MailyVariablesListView } from './views/maily-variables-list-view';
3546
import { HTMLCodeBlockView } from './views/html-view';
36-
import { CalculateVariablesProps, insertVariableToEditor, VariableFrom } from './variables/variables';
3747
import { VariablePill } from '@/components/variable/variable-pill';
3848
import { IsAllowedVariable } from '@/utils/parseStepVariables';
39-
import { StepResponseDto } from '@novu/shared';
40-
import { createDigestBlock } from './blocks/digest';
4149

50+
import type { Editor as TiptapEditor } from '@tiptap/core';
4251
export const VARIABLE_TRIGGER_CHARACTER = '{{';
4352

4453
/**
@@ -117,12 +126,29 @@ export const createEditorBlocks = (props: {
117126
return blocks;
118127
};
119128

129+
const getAvailableBlocks = (blocks: BlockGroupItem[], editor: TiptapEditor | null) => {
130+
// 'Repeat' and 'Digest' blocks can't be used inside another 'Repeat' block
131+
const isInsideRepeat = editor && isInsideRepeatBlock(editor);
132+
133+
if (isInsideRepeat) {
134+
const filteredBlocks = ['Repeat', 'Digest block'];
135+
136+
return blocks.map((block) => ({
137+
...block,
138+
commands: block.commands.filter((cmd) => !filteredBlocks.includes(cmd.title)),
139+
}));
140+
}
141+
142+
return blocks;
143+
};
144+
120145
export const createExtensions = (props: {
121146
handleCalculateVariables: (props: CalculateVariablesProps) => Variables | undefined;
122147
parsedVariables: { isAllowedVariable: IsAllowedVariable };
148+
blocks: BlockGroupItem[];
123149
isEnhancedDigestEnabled: boolean;
124150
}) => {
125-
const { handleCalculateVariables, parsedVariables, isEnhancedDigestEnabled } = props;
151+
const { handleCalculateVariables, parsedVariables, blocks, isEnhancedDigestEnabled } = props;
126152

127153
return [
128154
RepeatExtension.extend({
@@ -139,6 +165,14 @@ export const createExtensions = (props: {
139165
};
140166
},
141167
}),
168+
SlashCommandExtension.configure({
169+
suggestion: {
170+
...getSlashCommandSuggestions(blocks),
171+
items: ({ query, editor }) => {
172+
return searchSlashCommands(query, editor, getAvailableBlocks(blocks, editor));
173+
},
174+
},
175+
}),
142176
VariableExtension.extend({
143177
addNodeView() {
144178
return ReactNodeViewRenderer(createVariableView(parsedVariables.isAllowedVariable), {

apps/dashboard/src/components/workflow-editor/steps/email/maily.tsx

+12-6
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,10 @@ export const Maily = ({ value, onChange, className, ...rest }: MailyProps) => {
3939
const [_, setEditor] = useState<any>();
4040
const track = useTelemetry();
4141

42+
const blocks = useMemo(() => {
43+
return createEditorBlocks({ track, digestStepBeforeCurrent, isEnhancedDigestEnabled });
44+
}, [digestStepBeforeCurrent, isEnhancedDigestEnabled, track]);
45+
4246
const handleCalculateVariables = useCallback(
4347
({ query, editor, from }: { query: string; editor: TiptapEditor; from: VariableFrom }) => {
4448
return calculateVariables({
@@ -64,8 +68,14 @@ export const Maily = ({ value, onChange, className, ...rest }: MailyProps) => {
6468
);
6569

6670
const extensions = useMemo(
67-
() => createExtensions({ handleCalculateVariables, parsedVariables, isEnhancedDigestEnabled }),
68-
[handleCalculateVariables, parsedVariables, isEnhancedDigestEnabled]
71+
() =>
72+
createExtensions({
73+
handleCalculateVariables,
74+
parsedVariables,
75+
blocks,
76+
isEnhancedDigestEnabled,
77+
}),
78+
[handleCalculateVariables, parsedVariables, blocks, isEnhancedDigestEnabled]
6979
);
7080

7181
/*
@@ -109,10 +119,6 @@ export const Maily = ({ value, onChange, className, ...rest }: MailyProps) => {
109119
[onChange]
110120
);
111121

112-
const blocks = useMemo(() => {
113-
return createEditorBlocks({ track, digestStepBeforeCurrent, isEnhancedDigestEnabled });
114-
}, [track]);
115-
116122
const _Editor = isEnhancedDigestEnabled ? EditorDigest : Editor;
117123

118124
return (

apps/dashboard/src/components/workflow-editor/steps/email/variables/variables.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -286,8 +286,8 @@ const updateRepeatBlockChildAliases = (editor: Editor, isEnhancedDigestEnabled:
286286
.run();
287287
};
288288

289-
const isInsideRepeatBlock = (editor: TiptapEditor): boolean => {
290-
return findRepeatBlock(editor) !== null;
289+
export const isInsideRepeatBlock = (editor: TiptapEditor): boolean => {
290+
return editor?.isActive('repeat') ?? false;
291291
};
292292

293293
const getRepeatBlockEachVariables = (editor: TiptapEditor): Array<LiquidVariable> => {

0 commit comments

Comments
 (0)