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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ and this project adheres to
- πŸ›(backend) fix s3 version_id validation
- πŸ›(frontend) retry check media status after page reload #1555
- πŸ›(frontend) fix Interlinking memory leak #1560
- πŸ›(frontend) button new doc UI fix #1557
- πŸ›(frontend) interlinking UI fix #1557

## [3.8.2] - 2025-10-17

Expand Down
2 changes: 2 additions & 0 deletions src/frontend/apps/e2e/__tests__/app-impress/doc-grid.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,8 @@ test.describe('Document grid item options', () => {
test('it deletes the document', async ({ page, browserName }) => {
const [docTitle] = await createDoc(page, `delete doc`, browserName);

await verifyDocName(page, docTitle);

await page.goto('/');

await expect(page.getByText(docTitle)).toBeVisible();
Expand Down
27 changes: 26 additions & 1 deletion src/frontend/apps/e2e/__tests__/app-impress/doc-header.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,18 @@ test.describe('Doc Header', () => {
await createDoc(page, 'doc-update-emoji', browserName, 1);

const emojiPicker = page.locator('.--docs--doc-title').getByRole('button');
const optionMenu = page.getByLabel('Open the document options');
const addEmojiMenuItem = page.getByRole('menuitem', { name: 'Add emoji' });
const removeEmojiMenuItem = page.getByRole('menuitem', {
name: 'Remove emoji',
});

// Top parent should not have emoji picker
await expect(emojiPicker).toBeHidden();
await optionMenu.click();
await expect(addEmojiMenuItem).toBeHidden();
await expect(removeEmojiMenuItem).toBeHidden();
await page.keyboard.press('Escape');

const { name: docChild } = await createRootSubPage(
page,
Expand All @@ -80,13 +89,23 @@ test.describe('Doc Header', () => {

await verifyDocName(page, docChild);

await expect(emojiPicker).toBeVisible();
// Emoji picker should be hidden initially
await expect(emojiPicker).toBeHidden();

// Add emoji
await optionMenu.click();
await expect(removeEmojiMenuItem).toBeHidden();
await addEmojiMenuItem.click();
await expect(emojiPicker).toHaveText('πŸ“„');

// Change emoji
await emojiPicker.click({
delay: 100,
});
await page.getByRole('button', { name: 'πŸ˜€' }).first().click();
await expect(emojiPicker).toHaveText('πŸ˜€');

// Update title
const docTitle = page.getByRole('textbox', { name: 'Document title' });
await docTitle.fill('Hello Emoji World');
await docTitle.blur();
Expand All @@ -95,6 +114,12 @@ test.describe('Doc Header', () => {
// Check the tree
const row = await getTreeRow(page, 'Hello Emoji World');
await expect(row.getByText('πŸ˜€')).toBeVisible();

// Remove emoji
await optionMenu.click();
await expect(addEmojiMenuItem).toBeHidden();
await removeEmojiMenuItem.click();
await expect(emojiPicker).toBeHidden();
});

test('it deletes the doc', async ({ page, browserName }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,10 @@ test.describe('Doc Trashbin', () => {
await row.getByText(subDocName).click();
await verifyDocName(page, subDocName);

await expect(
page.locator('.--docs--editor-container.--docs--doc-deleted'),
).toBeVisible();

await expect(page.getByLabel('Alert deleted document')).toBeVisible();
await expect(page.getByRole('button', { name: 'Share' })).toBeDisabled();
await expect(page.locator('.bn-editor')).toHaveAttribute(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ test.describe('Doc Tree', () => {
await page.getByRole('menuitem', { name: 'Remove emoji' }).click();

await expect(row.getByText('πŸ˜€')).toBeHidden();
await expect(titleEmojiPicker).not.toHaveText('πŸ˜€');
await expect(titleEmojiPicker).toBeHidden();
});
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,10 @@ test.describe('Doc Visibility: Public', () => {
await expect(card).toBeVisible();
await expect(card.getByText('Reader')).toBeVisible();

await expect(
otherPage.locator('.--docs--editor-container.--docs--doc-readonly'),
).toBeVisible();

const otherEditor = await getEditor({ page: otherPage });
await expect(otherEditor).toHaveAttribute('contenteditable', 'false');
await expect(otherEditor.getByText('Hello Public Viewonly')).toBeVisible();
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/apps/impress/src/components/DropButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const StyledButton = styled(Button)<StyledButtonProps>`
font-weight: 500;
font-size: 0.938rem;
padding: 0;
${({ $css }) => $css};
border-radius: 4px;
&:hover {
background-color: var(
--c--components--button--primary-text--background--color-hover
Expand All @@ -41,6 +41,7 @@ const StyledButton = styled(Button)<StyledButtonProps>`
box-shadow: 0 0 0 2px var(--c--theme--colors--primary-400);
border-radius: 4px;
}
${({ $css }) => $css};
`;

export interface DropButtonProps {
Expand Down
12 changes: 8 additions & 4 deletions src/frontend/apps/impress/src/components/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const Icon = ({
iconName,
disabled,
variant = 'outlined',
$variation,
$variation = 'text',
...textProps
}: IconProps) => {
const hasLabel = 'aria-label' in textProps || 'aria-labelledby' in textProps;
Expand Down Expand Up @@ -41,15 +41,19 @@ type IconOptionsProps = TextType & {
isHorizontal?: boolean;
};

export const IconOptions = ({ isHorizontal, ...props }: IconOptionsProps) => {
export const IconOptions = ({
isHorizontal,
$css,
...props
}: IconOptionsProps) => {
return (
<Icon
{...props}
iconName={isHorizontal ? 'more_horiz' : 'more_vert'}
$css={css`
user-select: none;
${props.$css}
${$css}
`}
{...props}
/>
);
};
5 changes: 5 additions & 0 deletions src/frontend/apps/impress/src/cunningham/cunningham-style.css
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@
contain: content;
}

.c__button--medium {
min-height: var(--c--components--button--medium-height);
height: auto;
}

/**
* Modal
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ export function useAuthQuery(
staleTime: 1000 * 60 * 15, // 15 minutes
retry: (failureCount, error) => {
// we assume that a 401 means the user is not logged in
if (error.status == 401) {
if (error.status === 401) {
return false;
}
return failureCount < DEFAULT_QUERY_RETRY;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ import {
useUploadStatus,
} from '../hook';
import { useEditorStore } from '../stores';
import { cssEditor } from '../styles';
import { DocsBlockNoteEditor } from '../types';
import { randomColor } from '../utils';

Expand Down Expand Up @@ -169,7 +170,7 @@ export const BlockNoteEditor = ({ doc, provider }: BlockNoteEditorProps) => {
}, [setEditor, editor]);

return (
<Box ref={refEditorContainer}>
<Box ref={refEditorContainer} $css={cssEditor}>
{errorAttachment && (
<Box $margin={{ bottom: 'big', top: 'none', horizontal: 'large' }}>
<TextErrors
Expand Down Expand Up @@ -225,12 +226,14 @@ export const BlockNoteReader = ({ initialContent }: BlockNoteReaderProps) => {
useHeadings(editor);

return (
<BlockNoteView
editor={editor}
editable={false}
theme="light"
formattingToolbar={false}
slashMenu={false}
/>
<Box $css={cssEditor}>
<BlockNoteView
editor={editor}
editable={false}
theme="light"
formattingToolbar={false}
slashMenu={false}
/>
</Box>
);
};
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import clsx from 'clsx';
import { useEffect } from 'react';
import { css } from 'styled-components';

Expand All @@ -12,8 +13,6 @@ import { TableContent } from '@/docs/doc-table-content/';
import { useSkeletonStore } from '@/features/skeletons';
import { useResponsiveStore } from '@/stores';

import { cssEditor } from '../styles';

import { BlockNoteEditor, BlockNoteReader } from './BlockNoteEditor';

interface DocEditorContainerProps {
Expand Down Expand Up @@ -55,10 +54,13 @@ export const DocEditorContainer = ({
>
<Box $css="flex:1;" $position="relative" $width="100%">
<Box
$padding={{ top: 'md' }}
$padding={{ top: 'md', bottom: '2rem' }}
$background="white"
$css={cssEditor(readOnly, isDeletedDoc)}
className="--docs--editor-container"
className={clsx('--docs--editor-container', {
'--docs--doc-readonly': readOnly,
'--docs--doc-deleted': isDeletedDoc,
})}
$height="100%"
>
{docEditor}
</Box>
Expand All @@ -77,7 +79,9 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
const { isDesktop } = useResponsiveStore();
const { provider, isReady } = useProviderStore();
const { isEditable, isLoading } = useIsCollaborativeEditable(doc);
const readOnly = !doc.abilities.partial_update || !isEditable || isLoading;
const isDeletedDoc = !!doc.deleted_at;
const readOnly =
!doc.abilities.partial_update || !isEditable || isLoading || isDeletedDoc;
const { setIsSkeletonVisible } = useSkeletonStore();
const isProviderReady = isReady && provider;

Expand Down Expand Up @@ -117,7 +121,7 @@ export const DocEditor = ({ doc }: DocEditorProps) => {
<BlockNoteEditor doc={doc} provider={provider} />
)
}
isDeletedDoc={!!doc.deleted_at}
isDeletedDoc={isDeletedDoc}
readOnly={readOnly}
/>
</>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const LinkSelected = ({ url, title }: LinkSelectedProps) => {
onClick={handleClick}
draggable="false"
$css={css`
display: inline;
display: contents;
padding: 0.1rem 0.4rem;
border-radius: 4px;
& svg {
Expand All @@ -89,6 +89,10 @@ const LinkSelected = ({ url, title }: LinkSelectedProps) => {
background-color: ${colorsTokens['greyscale-100']};
}
transition: background-color 0.2s ease-in-out;

.--docs--doc-deleted & {
pointer-events: none;
}
`}
>
{emoji ? (
Expand Down
16 changes: 6 additions & 10 deletions src/frontend/apps/impress/src/features/docs/doc-editor/styles.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { css } from 'styled-components';

export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css`
export const cssEditor = css`
&,
& > .bn-container,
& .ProseMirror {
height: 100%;
padding-bottom: 2rem;
}

& .ProseMirror {
/**
* WCAG Accessibility contrast fixes for BlockNote editor
*/
Expand Down Expand Up @@ -131,13 +132,6 @@ export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css`
.bn-block-outer:not([data-prev-depth-changed]):before {
border-left: none;
}

${isDeletedDoc &&
`
.node-interlinkingLinkInline button {
pointer-events: none;
}
`}
}

& .bn-editor {
Expand Down Expand Up @@ -187,8 +181,10 @@ export const cssEditor = (readonly: boolean, isDeletedDoc: boolean) => css`
}

@media screen and (width <= 560px) {
.--docs--doc-readonly & .bn-editor {
padding-left: 10px;
}
& .bn-editor {
${readonly && `padding-left: 10px;`}
padding-right: 10px;
}
.bn-side-menu[data-block-type='heading'][data-level='1'] {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export const BoutonShare = ({

return (
<Button
color="tertiary-text"
color="primary-text"
onClick={open}
size="medium"
disabled={isDisabled}
Expand Down
Loading
Loading