Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to
### Added

- ✨(tracking) add UTM parameters to shared document links
- ✨(frontend) add floating bar with leftpanel collapse button #1876
- ✨(frontend) Can print a doc #1832
- ✨(backend) manage reconciliation requests for user accounts #1878
- 👷(CI) add GHCR workflow for forked repo testing #1851
Expand Down
16 changes: 9 additions & 7 deletions src/frontend/apps/e2e/__tests__/app-impress/doc-comments.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ test.describe('Doc Comments', () => {
// We add a comment with the first user
const editor = await writeInEditor({ page, text: 'Hello World' });
await editor.getByText('Hello').selectText();
await page.getByRole('button', { name: 'Comment' }).click();
await page.getByRole('button', { name: 'Comment', exact: true }).click();

const thread = page.locator('.bn-thread');
await thread.getByRole('paragraph').first().fill('This is a comment');
Expand Down Expand Up @@ -124,7 +124,7 @@ test.describe('Doc Comments', () => {
// Checks add react reaction
const editor = await writeInEditor({ page, text: 'Hello' });
await editor.getByText('Hello').selectText();
await page.getByRole('button', { name: 'Comment' }).click();
await page.getByRole('button', { name: 'Comment', exact: true }).click();

const thread = page.locator('.bn-thread');
await thread.getByRole('paragraph').first().fill('This is a comment');
Expand Down Expand Up @@ -191,7 +191,7 @@ test.describe('Doc Comments', () => {

/* Delete the last comment remove the thread */
await editor.getByText('Hello').selectText();
await page.getByRole('button', { name: 'Comment' }).click();
await page.getByRole('button', { name: 'Comment', exact: true }).click();

await thread.getByRole('paragraph').first().fill('This is a new comment');
await thread.locator('[data-test="save"]').click();
Expand Down Expand Up @@ -249,7 +249,9 @@ test.describe('Doc Comments', () => {
editor.getByText('Hello, I can edit the document'),
).toBeVisible();
await otherEditor.getByText('Hello').selectText();
await otherPage.getByRole('button', { name: 'Comment' }).click();
await otherPage
.getByRole('button', { name: 'Comment', exact: true })
.click();
const otherThread = otherPage.locator('.bn-thread');
await otherThread
.getByRole('paragraph')
Expand Down Expand Up @@ -280,7 +282,7 @@ test.describe('Doc Comments', () => {
await expect(otherThread).toBeHidden();
await otherEditor.getByText('Hello').selectText();
await expect(
otherPage.getByRole('button', { name: 'Comment' }),
otherPage.getByRole('button', { name: 'Comment', exact: true }),
).toBeHidden();

await otherPage.reload();
Expand Down Expand Up @@ -334,7 +336,7 @@ test.describe('Doc Comments', () => {
// We add a comment in the first document
const editor1 = await writeInEditor({ page, text: 'Document One' });
await editor1.getByText('Document One').selectText();
await page.getByRole('button', { name: 'Comment' }).click();
await page.getByRole('button', { name: 'Comment', exact: true }).click();

const thread1 = page.locator('.bn-thread');
await thread1.getByRole('paragraph').first().fill('Comment in Doc One');
Expand Down Expand Up @@ -388,7 +390,7 @@ test.describe('Doc Comments mobile', () => {
// Checks add react reaction
const editor = await writeInEditor({ page, text: 'Hello' });
await editor.getByText('Hello').selectText();
await page.getByRole('button', { name: 'Comment' }).click();
await page.getByRole('button', { name: 'Comment', exact: true }).click();

const thread = page.locator('.bn-thread');
await thread.getByRole('paragraph').first().fill('This is a comment');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -410,7 +410,7 @@ test.describe('Doc Editor', () => {
const editor = page.locator('.ProseMirror');
await editor.getByText('Hello').selectText();

await page.getByRole('button', { name: 'AI' }).click();
await page.getByRole('button', { name: 'AI', exact: true }).click();

await expect(
page.getByRole('menuitem', { name: 'Use as prompt' }),
Expand Down Expand Up @@ -494,11 +494,13 @@ test.describe('Doc Editor', () => {
await editor.getByText('Hello').selectText();

if (!ai_transform && !ai_translate) {
await expect(page.getByRole('button', { name: 'AI' })).toBeHidden();
await expect(
page.getByRole('button', { name: 'AI', exact: true }),
).toBeHidden();
return;
}

await page.getByRole('button', { name: 'AI' }).click();
await page.getByRole('button', { name: 'AI', exact: true }).click();

if (ai_transform) {
await expect(
Expand Down
38 changes: 38 additions & 0 deletions src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
mockedDocument,
verifyDocName,
} from './utils-common';
import { writeInEditor } from './utils-editor';
import {
connectOtherUserToDoc,
mockedAccesses,
Expand All @@ -20,6 +21,43 @@ test.beforeEach(async ({ page }) => {
});

test.describe('Doc Header', () => {
test('toggles panel collapse from floating bar button', async ({
page,
browserName,
}) => {
const [docTitle] = await createDoc(
page,
'doc-floating-bar',
browserName,
1,
);

const collapseButton = page.getByTestId('floating-bar-toggle-left-panel');
await expect(collapseButton).toBeVisible();

// Panel open
await expect(collapseButton).toHaveAttribute('aria-expanded', 'true');
await expect(collapseButton.getByText(docTitle)).toBeHidden();

// Collapse panel
await collapseButton.click();
await expect(collapseButton).toHaveAttribute('aria-expanded', 'false');
await expect(collapseButton.getByText(docTitle)).toBeHidden();

// When the title is not visible in the viewport, the button should show the title
const editor = await writeInEditor({ page, text: 'Lorem ipsum' });
for (let i = 0; i < 25; i++) {
await editor.press('Enter');
}
await writeInEditor({ page, text: 'Lorem ipsum 2' });
await expect(collapseButton.getByText(docTitle)).toBeVisible();

// Expand panel and check the title is hidden again
await collapseButton.click();
await expect(collapseButton).toHaveAttribute('aria-expanded', 'true');
await expect(collapseButton.getByText(docTitle)).toBeHidden();
});

test('it checks the element are correctly displayed', async ({
page,
browserName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import clsx from 'clsx';
import { useEffect, useState } from 'react';

import { Box, Loading } from '@/components';
import { DocHeader } from '@/docs/doc-header/';
import { DocHeader, FloatingBar } from '@/docs/doc-header/';
import {
Doc,
LinkReach,
Expand Down Expand Up @@ -35,6 +35,7 @@ export const DocEditorContainer = ({

return (
<>
{isDesktop && <FloatingBar />}
<Box
$maxWidth="868px"
$width="100%"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const DocHeader = ({ doc }: DocHeaderProps) => {
<>
<Box
$width="100%"
$padding={{ top: isDesktop ? '50px' : 'md' }}
$padding={{ top: isDesktop ? '0' : 'md' }}
$gap={spacingsTokens['base']}
aria-label={t('It is the card information about the document.')}
className="--docs--doc-header"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
import SimpleFileIcon from '@/features/docs/doc-management/assets/simple-document.svg';
import { useResponsiveStore } from '@/stores';

export const CLASS_DOC_TITLE = '--docs--doc-title';

interface DocTitleProps {
doc: Doc;
}
Expand All @@ -39,13 +41,15 @@ export const DocTitleText = () => {
const { untitledDocument } = useTrans();

return (
<Text
as="h2"
$margin={{ all: 'none', left: 'none' }}
$size={isMobile ? 'h4' : 'h2'}
>
{currentDoc?.title || untitledDocument}
</Text>
<Box className={CLASS_DOC_TITLE} $direction="row" $align="center">
<Text
as="h2"
$margin={{ all: 'none', left: 'none' }}
$size={isMobile ? 'h4' : 'h2'}
>
{currentDoc?.title || untitledDocument}
</Text>
</Box>
);
};

Expand All @@ -65,6 +69,7 @@ const DocTitleEmojiPicker = ({ doc }: DocTitleProps) => {
placement="top"
>
<Box
className={CLASS_DOC_TITLE}
$css={css`
padding: 4px;
padding-top: 3px;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import { useMemo } from 'react';
import { css } from 'styled-components';

import { Box } from '@/components';
import { useCunninghamTheme } from '@/cunningham/useCunninghamTheme';
import { LeftPanelCollapseButton } from '@/features/left-panel';
import { useResponsiveStore } from '@/stores';

/**
* Sticky bar trick (desktop):
* - MainContent has padding `base`; we extend the bar width and apply
* matching negative margins so it aligns with the scroll area edges.
*
* Mobile: returns null to avoid header overlap.
*/
export const FloatingBar = () => {
const { spacingsTokens } = useCunninghamTheme();
const { isDesktop } = useResponsiveStore();

const FLOATING_STYLES = useMemo(() => {
const base = spacingsTokens['base'];
const sm = spacingsTokens['sm'];
return css`
position: sticky;
top: calc(-${base});
left: 0;
right: 0;
width: calc(100% + ${base} + ${base});
min-height: 64px;
padding: ${sm};
margin-left: calc(-${base});
margin-right: calc(-${base});
margin-top: calc(-${base});
z-index: 1000;
display: flex;
align-items: flex-start;
justify-content: flex-start;
isolation: isolate;
&::before {
content: '';
position: absolute;
inset: 0;
z-index: -1;
background: linear-gradient(
180deg,
#fff 0%,
rgba(255, 255, 255, 0) 100%
);
backdrop-filter: blur(1px);
-webkit-backdrop-filter: blur(1px);
mask-image: linear-gradient(180deg, black 50%, transparent 100%);
-webkit-mask-image: linear-gradient(
180deg,
black 50%,
transparent 100%
);
}
> * {
position: relative;
z-index: 1;
}
`;
}, [spacingsTokens]);

if (!isDesktop) {
return null;
}

return (
<Box
className="--docs--floating-bar"
data-testid="floating-bar"
$css={FLOATING_STYLES}
>
<LeftPanelCollapseButton />
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './DocHeader';
export * from './DocTitle';
export * from './FloatingBar';
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ export const TableContent = () => {
$width={!isOpen ? '40px' : '200px'}
$height={!isOpen ? '40px' : 'auto'}
$maxHeight="calc(50vh - 60px)"
$zIndex={1000}
$zIndex={2000}
$align="center"
$padding={isOpen ? 'xs' : '0'}
$justify="center"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,22 @@ import { useLeftPanelStore } from '@/features/left-panel';

export const ButtonTogglePanel = () => {
const { t } = useTranslation();
const { isPanelOpen, togglePanel } = useLeftPanelStore();
const { isPanelOpenMobile, togglePanel } = useLeftPanelStore();

return (
<Button
size="medium"
onClick={() => togglePanel()}
aria-label={t(
isPanelOpen ? 'Close the header menu' : 'Open the header menu',
isPanelOpenMobile ? 'Close the header menu' : 'Open the header menu',
)}
aria-expanded={isPanelOpen}
aria-expanded={isPanelOpenMobile}
variant="tertiary"
icon={
<Icon $withThemeInherited iconName={isPanelOpen ? 'close' : 'menu'} />
<Icon
$withThemeInherited
iconName={isPanelOpenMobile ? 'close' : 'menu'}
/>
}
className="--docs--button-toggle-panel"
data-testid="header-menu-toggle"
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { Box, Icon, StyledLink, Text } from '@/components';
import { useCunninghamTheme } from '@/cunningham';
import { DocDefaultFilter } from '@/docs/doc-management';
import { useLeftPanelStore } from '@/features/left-panel';
import { useResponsiveStore } from '@/stores';

export const LeftPanelTargetFilters = () => {
const { t } = useTranslation();
const pathname = usePathname();
const searchParams = useSearchParams();

const { togglePanel } = useLeftPanelStore();
const { isDesktop } = useResponsiveStore();
const { closePanel } = useLeftPanelStore();
const { colorsTokens, spacingsTokens } = useCunninghamTheme();

const target =
Expand Down Expand Up @@ -49,8 +51,10 @@ export const LeftPanelTargetFilters = () => {
return `${pathname}?${params.toString()}`;
};

const handleClick = () => {
togglePanel();
const handleFilterClick = () => {
if (!isDesktop) {
closePanel();
}
};

return (
Expand All @@ -70,9 +74,7 @@ export const LeftPanelTargetFilters = () => {
href={href}
aria-label={query.label}
aria-current={isActive ? 'page' : undefined}
onClick={() => {
handleClick();
}}
onClick={handleFilterClick}
$css={css`
display: flex;
align-items: center;
Expand Down
Loading
Loading