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
17 changes: 17 additions & 0 deletions apps/frontend/.storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { StorybookConfig } from '@storybook/react-vite';
import path from 'path';

const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(js|jsx|ts|tsx|mdx)'],
addons: [],
framework: {
name: '@storybook/react-vite',
options: {
builder: {
viteConfigPath: path.resolve(__dirname, 'vite.config.ts'),
},
},
},
};

export default config;
35 changes: 35 additions & 0 deletions apps/frontend/.storybook/preview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import type { Preview } from '@storybook/react';
import React from 'react';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import { UIProvider } from '@packmind/ui';

const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
staleTime: Infinity,
},
},
});

const preview: Preview = {
decorators: [
(Story) => (
<QueryClientProvider client={queryClient}>
<UIProvider>
<Story />
</UIProvider>
</QueryClientProvider>
),
],
parameters: {
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
};

export default preview;
35 changes: 35 additions & 0 deletions apps/frontend/.storybook/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { defineConfig } from 'vite';
import { nxViteTsPaths } from '@nx/vite/plugins/nx-tsconfig-paths.plugin';
import path from 'path';

export default defineConfig(() => {
// Determine edition mode (defaults to OSS if not explicitly set to 'proprietary')
const isOssMode = process.env.PACKMIND_EDITION !== 'proprietary';

// Configure resolve aliases based on edition
const resolveAliases = isOssMode
? {
'@packmind/proprietary/frontend': path.resolve(
__dirname,
'../src/domain/editions/stubs',
),
}
: {
'@packmind/proprietary/frontend': path.resolve(__dirname, '../src'),
};

return {
root: path.resolve(__dirname, '..'),
cacheDir: '../../../node_modules/.vite/apps/frontend-storybook',
assetsInclude: ['**/*.svg', '**/*.png'],
define: {
__PACKMIND_EDITION__: JSON.stringify(
process.env.PACKMIND_EDITION || 'oss',
),
},
resolve: {
alias: resolveAliases,
},
plugins: [nxViteTsPaths()],
};
});
17 changes: 17 additions & 0 deletions apps/frontend/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,23 @@
"options": {
"command": "nx dev frontend"
}
},
"storybook": {
"executor": "nx:run-commands",
"continuous": true,
"options": {
"cwd": "apps/frontend",
"command": "storybook dev -p 6006"
}
},
"build-storybook": {
"executor": "nx:run-commands",
"cache": true,
"outputs": ["{projectRoot}/storybook-static"],
"options": {
"cwd": "apps/frontend",
"command": "storybook build"
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ import {
import { HighlightedText, HighlightedRuleBox } from '../HighlightedContent';
import { UnifiedMarkdownViewer } from '../UnifiedMarkdownViewer';
import { useDiffNavigation } from '../../hooks/useDiffNavigation';
import { renderMarkdownDiffOrPreview } from '../SkillReviewDetail/SkillContent/renderMarkdownDiffOrPreview';

interface ProposalReviewPanelProps {
selectedStandard: Standard | undefined;
Expand Down Expand Up @@ -244,15 +243,24 @@ export function ProposalReviewPanel({
? renderDiffText(payload.oldValue, payload.newValue)
: selectedStandard.name}
</PMText>
{renderMarkdownDiffOrPreview(
isDescriptionDiff,
showPreview,
payload,
selectedStandard.description,
{
previewPaddingVariant: 'none',
defaultPaddingVariant: 'none',
},
{isDescriptionDiff ? (
<UnifiedMarkdownViewer
key={showPreview ? 'preview' : 'diff'}
oldValue={payload.oldValue}
newValue={payload.newValue}
proposalNumbers={[
proposalNumberMap.get(reviewingProposal.id) ?? 0,
]}
displayMode={showPreview ? 'unified' : 'diff'}
/>
) : (
<MarkdownEditorProvider>
<MarkdownEditor
defaultValue={selectedStandard.description}
readOnly
paddingVariant="none"
/>
</MarkdownEditorProvider>
)}

{/* Rules Section */}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
import type { Meta, StoryObj } from '@storybook/react';
import {
UnifiedMarkdownViewer,
UnifiedMarkdownViewerProps,
} from './UnifiedMarkdownViewer';

const MultiViewer: React.FunctionComponent<
Omit<UnifiedMarkdownViewerProps, 'displayMode'>
> = (props) => {
return (
<div style={{ display: 'flex', flexDirection: 'row', gap: '2em' }}>
<div style={{ width: '50%' }}>
<h1>Unified view</h1>
<UnifiedMarkdownViewer {...props} displayMode={'unified'} />
</div>

<div style={{ flex: '1 1 0px' }}>
<h1>Diff view</h1>
<UnifiedMarkdownViewer {...props} displayMode={'diff'} />
</div>
</div>
);
};

const meta: Meta<typeof MultiViewer> = {
title: 'ChangeProposals/UnifiedMarkdownViewer',
component: MultiViewer,
parameters: {
layout: 'padded',
},
tags: ['autodocs'],
};

export default meta;
type Story = StoryObj<typeof meta>;

export const MarkdownFormatting: Story = {
args: {
oldValue: `# My title

This was my content

There was a line here.

## My sub-heading

My list:
- one item
- another item

# Code example

\`\`\`javascript
function hello() {
console.log('Hello');
}
\`\`\`
`,
newValue: `# My title

This is my updated content

## My sub-heading

My list:
- first item
- a new item
- another item

# Example

\`\`\`javascript
function hello() {
console.log('Hello, ' + name);
}
\`\`\``,
proposalNumbers: [1],
},
};

export const TagChanges: Story = {
args: {
oldValue: '# My title\n\nThis was my content',
newValue: '## My title\n\nThis is my **content**',
proposalNumbers: [1],
},
};

export const MultipleProposals: Story = {
args: {
oldValue: 'This is my content',
newValue: 'This is my updated content',
proposalNumbers: [1, 2, 3],
},
};

export const CodeBlock: Story = {
args: {
oldValue: `# Example

\`\`\`javascript
function hello() {
console.log('Hello');
}
\`\`\``,
newValue: `# Example

\`\`\`javascript
function hello(name) {
console.log('Hello, ' + name);
}
\`\`\``,
proposalNumbers: [1],
},
};

export const ListChanges: Story = {
args: {
oldValue: `# Todo List

- Item 1
- Item 2
- Item 3`,
newValue: `# Todo List

- Item 1
- Updated Item 2
- Item 3
- Item 4`,
proposalNumbers: [1],
},
};

export const ComplexChanges: Story = {
args: {
oldValue: `# My title

This was my content

There was a line here.

## My sub-heading

My list:
- one item
- another item`,
newValue: `# My title

This is my updated content

## My sub-heading

My list:
- first item
- a new item
- another item`,
proposalNumbers: [1, 2],
},
};
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
import React from 'react';
import { PMBox } from '@packmind/ui';
import { MilkdownProvider } from '@milkdown/react';
import { DiffMarkdownEditor } from '../../../shared/components/editor/DiffMarkdownEditor';
import {
DiffMarkdownEditor,
IDiffMarkdownEditorProps,
} from '../../../shared/components/editor/DiffMarkdownEditor';

interface UnifiedMarkdownViewerProps {
export interface UnifiedMarkdownViewerProps {
oldValue: string;
newValue: string;
proposalNumbers: number[];
displayMode?: IDiffMarkdownEditorProps['displayMode'];
}

/**
Expand All @@ -18,6 +22,7 @@ export function UnifiedMarkdownViewer({
oldValue,
newValue,
proposalNumbers,
displayMode,
}: UnifiedMarkdownViewerProps) {
return (
<PMBox data-diff-section>
Expand All @@ -26,6 +31,7 @@ export function UnifiedMarkdownViewer({
oldValue={oldValue}
newValue={newValue}
proposalNumbers={proposalNumbers}
displayMode={displayMode ?? 'unified'}
paddingVariant="none"
/>
</MilkdownProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { buildDiffHtml } from './markdownDiff';

/**
* Builds inline diff markdown content for the "diff" display mode.
* Uses buildDiffHtml to generate HTML with <ins> and <del> tags
* showing additions and deletions inline.
*/
export function buildInlineDiffMarkdown(
oldValue: string,
newValue: string,
): string {
return buildDiffHtml(oldValue, newValue);
}
Loading