Merge pull request #1729 from mermaid-js/release-promotion
Release live editor
This commit is contained in:
@@ -2,6 +2,6 @@ MERMAID_DOMAIN=''
|
||||
MERMAID_ANALYTICS_URL=''
|
||||
MERMAID_RENDERER_URL='https://mermaid.ink'
|
||||
MERMAID_KROKI_RENDERER_URL='https://kroki.io'
|
||||
MERMAID_IS_ENABLED_MERMAID_CHART_LINKS=''
|
||||
MERMAID_IS_ENABLED_MERMAID_CHART_LINKS='true'
|
||||
|
||||
# cp .env .env.local to make local changes
|
||||
|
||||
@@ -49,6 +49,6 @@ jobs:
|
||||
- uses: actions/upload-artifact@v4
|
||||
if: ${{ !cancelled() }}
|
||||
with:
|
||||
name: playwright-report
|
||||
path: playwright-report/
|
||||
retention-days: 30
|
||||
name: test-results
|
||||
path: test-results/
|
||||
retention-days: 7
|
||||
|
||||
+1
-1
@@ -115,7 +115,7 @@
|
||||
]
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=20.19.1"
|
||||
"node": ">=20.19.0"
|
||||
},
|
||||
"packageManager": "pnpm@10.10.0+sha512.d615db246fe70f25dcfea6d8d73dee782ce23e2245e3c4f6f888249fb568149318637dca73c2c5c8ef2a4ca0d5657fb9567188bfab47f566d1ee6ce987815c39",
|
||||
"pnpm": {
|
||||
|
||||
@@ -32,20 +32,25 @@
|
||||
<ExclamationCircleIcon class="size-6 text-destructive" aria-hidden="true" />
|
||||
<div class="flex flex-col">
|
||||
<p>Syntax error</p>
|
||||
{#if env.isEnabledMermaidChartLinks}
|
||||
<p class="text-xs text-white/60">Create a free account to repair with AI</p>
|
||||
{#if env.isEnabledMermaidChartLinks && $stateStore.editorMode === 'code'}
|
||||
<p class="text-xs text-white/60" data-testid={TID.aiHelpText}>
|
||||
Create a free account to repair with AI
|
||||
</p>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
<McWrapper>
|
||||
<Button
|
||||
variant="accent"
|
||||
size="sm"
|
||||
href={$urlsStore.mermaidChart({ medium: 'ai_repair' }).save}>
|
||||
<MermaidChartIcon />
|
||||
AI Repair
|
||||
</Button>
|
||||
</McWrapper>
|
||||
{#if $stateStore.editorMode === 'code'}
|
||||
<McWrapper>
|
||||
<Button
|
||||
variant="accent"
|
||||
size="sm"
|
||||
data-testid={TID.aiRepairButton}
|
||||
href={$urlsStore.mermaidChart({ medium: 'ai_repair' }).save}>
|
||||
<MermaidChartIcon />
|
||||
AI Repair
|
||||
</Button>
|
||||
</McWrapper>
|
||||
{/if}
|
||||
</div>
|
||||
<output class="max-h-32 overflow-auto bg-muted p-2" name="mermaid-error" for="editor">
|
||||
<pre>{$stateStore.error?.toString()}</pre>
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
export const TID = {
|
||||
aiHelpText: 'ai-help-text',
|
||||
aiRepairButton: 'ai-repair-button',
|
||||
copyMarkdown: 'copy-markdown',
|
||||
diagramDocumentationButton: 'diagram-documentation-button',
|
||||
downloadPNG: 'download-PNG',
|
||||
|
||||
@@ -21,37 +21,6 @@
|
||||
|
||||
const commonParams = { utm_source: C.utmSource, utm_medium: 'banner_ad' } as const;
|
||||
|
||||
const randomTagLines: Taglines[] = [
|
||||
{
|
||||
label: 'Customize your layout and design in Mermaid Chart’s whiteboard!',
|
||||
url: {
|
||||
path: '/whiteboard',
|
||||
params: { utm_campaign: 'whiteboard' }
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Customize your layout and design in Mermaid Chart’s visual editor!',
|
||||
url: {
|
||||
path: '/whiteboard',
|
||||
params: { utm_campaign: 'visual_editor' }
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Customize your layout and design with Mermaid Chart’s GUI!',
|
||||
url: {
|
||||
path: '/whiteboard',
|
||||
params: { utm_campaign: 'gui' }
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Customize your layout and design in Mermaid Chart!',
|
||||
url: {
|
||||
path: '/whiteboard',
|
||||
params: { utm_campaign: 'visual_editor_whiteboard_gui' }
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
let taglines: Taglines[] = [
|
||||
{
|
||||
label: 'Replace ChatGPT Pro, Mermaid.live, and Lucid Chart with Mermaid Chart',
|
||||
@@ -66,33 +35,25 @@
|
||||
path: '/landing',
|
||||
params: { utm_campaign: 'team_collaboration' }
|
||||
}
|
||||
},
|
||||
{
|
||||
label: 'Customize your layout and design in Mermaid Chart’s visual editor!',
|
||||
url: {
|
||||
path: '/whiteboard',
|
||||
params: { utm_campaign: 'visual_editor' }
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const getRandomIndex = (array: unknown[]) => Math.floor(Math.random() * array.length);
|
||||
const getSessionHeadlineIndex = (): number => {
|
||||
const storageKey = 'mermaidBannerIndex';
|
||||
const storedIndex = sessionStorage.getItem(storageKey);
|
||||
|
||||
if (storedIndex) {
|
||||
return Number.parseInt(storedIndex, 10);
|
||||
}
|
||||
|
||||
const randomIndex = getRandomIndex(randomTagLines);
|
||||
sessionStorage.setItem(storageKey, randomIndex.toString());
|
||||
return randomIndex;
|
||||
};
|
||||
|
||||
const selectedHeadlineIndex = getSessionHeadlineIndex();
|
||||
const currentBannerSet = [...taglines, randomTagLines[selectedHeadlineIndex]];
|
||||
|
||||
let index = $state(getRandomIndex(currentBannerSet));
|
||||
let currentTagline = $derived(currentBannerSet[index]);
|
||||
let index = $state(getRandomIndex(taglines));
|
||||
let currentTagline = $derived(taglines[index]);
|
||||
let shouldAnimate = $state(true);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (shouldAnimate) {
|
||||
index = (index + 1) % currentBannerSet.length;
|
||||
index = (index + 1) % taglines.length;
|
||||
}
|
||||
}, 5000);
|
||||
|
||||
@@ -117,9 +78,9 @@
|
||||
class="col-start-1 row-start-1 flex items-center justify-center gap-4 no-underline"
|
||||
in:fade={{ delay: 800 }}
|
||||
out:fade={{ duration: 1000 }}>
|
||||
<span class="text-sm tracking-wider text-white">{currentTagline.label}</span>
|
||||
<span class="text-base tracking-wider text-white">{currentTagline.label}</span>
|
||||
<Button
|
||||
class="shrink-0 rounded-md bg-[#1E1A2E] px-3 py-1.5 text-sm font-semibold tracking-wide text-white hover:bg-[#261A56]">
|
||||
class="shrink-0 rounded-md bg-[#1E1A2E] px-3 py-1.5 text-base font-semibold tracking-wide text-white hover:bg-[#261A56]">
|
||||
Try now
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
import { test } from './test';
|
||||
|
||||
test.describe('Error display tests', () => {
|
||||
test('should show AI Repair button for syntax errors in Code tab', async ({ editPage }) => {
|
||||
// Enter code with syntax error
|
||||
await editPage.clearEditor();
|
||||
await editPage.typeInEditor('graph TD\nA --> B -->');
|
||||
|
||||
// Verify error is displayed
|
||||
await editPage.checkError('Syntax error');
|
||||
|
||||
// Verify AI Repair button and help text is shown in Code tab
|
||||
await editPage.checkAIHelperVisibility(true);
|
||||
});
|
||||
|
||||
test('should not show AI Repair button for errors in Config tab', async ({ editPage }) => {
|
||||
// First enter valid diagram
|
||||
await editPage.clearEditor();
|
||||
await editPage.typeInEditor('graph TD\nA --> B');
|
||||
|
||||
// Switch to Config tab
|
||||
await editPage.setEditorMode('Config');
|
||||
|
||||
// Enter invalid JSON in config
|
||||
await editPage.clearEditor();
|
||||
await editPage.typeInEditor('{\n "theme": "default",\n invalid json');
|
||||
|
||||
// Verify error is displayed
|
||||
await editPage.checkError('Syntax error');
|
||||
|
||||
// Verify AI Repair button and help text is NOT shown in Config tab
|
||||
await editPage.checkAIHelperVisibility(false);
|
||||
});
|
||||
});
|
||||
@@ -103,6 +103,13 @@ export class EditorPage {
|
||||
`Switch to ${theme === 'light' ? 'dark' : 'light'} theme`
|
||||
);
|
||||
}
|
||||
|
||||
async checkAIHelperVisibility(shouldBeVisible: boolean) {
|
||||
const button = this.page.getByTestId(TID.aiRepairButton);
|
||||
const helpText = this.page.getByTestId(TID.aiHelpText);
|
||||
await expect(button)[shouldBeVisible ? 'toBeVisible' : 'toBeHidden']();
|
||||
await expect(helpText)[shouldBeVisible ? 'toBeVisible' : 'toBeHidden']();
|
||||
}
|
||||
}
|
||||
|
||||
export const test = base.extend<{ editPage: EditorPage }>({
|
||||
|
||||
Reference in New Issue
Block a user