Skip to content

Commit 2a7c0ef

Browse files
committed
✨(frontend) create page from dropdown search
We are now able to create a new page from the dropdown search.
1 parent 155e7df commit 2a7c0ef

File tree

7 files changed

+127
-39
lines changed

7 files changed

+127
-39
lines changed

src/frontend/apps/e2e/__tests__/app-impress/doc-create.spec.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,28 @@ test.describe('Doc Create', () => {
5151
page.locator('.c__tree-view--row-content').getByText('Untitled document'),
5252
).toBeVisible();
5353
});
54+
55+
test('it creates a sub doc from interlinking dropdown', async ({
56+
page,
57+
browserName,
58+
}) => {
59+
const [title] = await createDoc(page, 'my-new-slash-doc', browserName, 1);
60+
61+
await verifyDocName(page, title);
62+
63+
await page.locator('.bn-block-outer').last().fill('/');
64+
await page.getByText('Link a doc').first().click();
65+
await page
66+
.locator('.quick-search-container')
67+
.getByText('New sub-doc')
68+
.click();
69+
70+
const input = page.getByRole('textbox', { name: 'doc title input' });
71+
await expect(input).toHaveText('');
72+
await expect(
73+
page.locator('.c__tree-view--row-content').getByText('Untitled document'),
74+
).toBeVisible();
75+
});
5476
});
5577

5678
test.describe('Doc Create: Not logged', () => {

src/frontend/apps/impress/src/components/BoxButton.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ const BoxButton = forwardRef<HTMLDivElement, BoxButtonType>(
3131
$background="none"
3232
$margin="none"
3333
$padding="none"
34+
$hasTransition
3435
$css={css`
3536
cursor: ${props.disabled ? 'not-allowed' : 'pointer'};
3637
border: none;
3738
outline: none;
38-
transition: all 0.2s ease-in-out;
3939
font-family: inherit;
4040
4141
color: ${props.disabled
Lines changed: 3 additions & 0 deletions
Loading

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/InterlinkingSearchInlineContent.tsx

Lines changed: 8 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
/* eslint-disable react-hooks/rules-of-hooks */
22
import { createReactInlineContentSpec } from '@blocknote/react';
3-
import { useTreeContext } from '@gouvfr-lasuite/ui-kit';
43
import { TFunction } from 'i18next';
5-
import { useRouter } from 'next/navigation';
6-
import { useCallback } from 'react';
74

85
import { DocsBlockNoteEditor } from '@/docs/doc-editor';
96
import LinkPageIcon from '@/docs/doc-editor/assets/doc-link.svg';
107
import AddPageIcon from '@/docs/doc-editor/assets/doc-plus.svg';
11-
import { Doc, useCreateChildDoc, useDocStore } from '@/docs/doc-management';
8+
import { useCreateChildDocTree, useDocStore } from '@/docs/doc-management';
129

1310
import { SearchPage } from './SearchPage';
1411

@@ -29,12 +26,12 @@ export const InterlinkingSearchInlineContent = createReactInlineContentSpec(
2926
return null;
3027
}
3128

32-
return <SearchPage {...props} />;
29+
return <SearchPage {...props} contentRef={props.contentRef} />;
3330
},
3431
},
3532
);
3633

37-
export const getInterlinkingMenuItems = (
34+
export const getInterlinkinghMenuItems = (
3835
editor: DocsBlockNoteEditor,
3936
t: TFunction<'translation', undefined>,
4037
group: string,
@@ -68,37 +65,11 @@ export const getInterlinkingMenuItems = (
6865
];
6966

7067
export const useGetInterlinkingMenuItems = () => {
71-
const treeContext = useTreeContext<Doc>();
72-
const router = useRouter();
7368
const { currentDoc } = useDocStore();
69+
const createChildDoc = useCreateChildDocTree(currentDoc?.id);
7470

75-
const { mutate: createChildDoc } = useCreateChildDoc({
76-
onSuccess: (createdDoc) => {
77-
const newDoc = {
78-
...createdDoc,
79-
children: [],
80-
childrenCount: 0,
81-
parentId: currentDoc?.id ?? undefined,
82-
};
83-
treeContext?.treeData.addChild(currentDoc?.id || null, newDoc);
84-
85-
router.push(`/docs/${newDoc.id}`);
86-
treeContext?.treeData.setSelectedNode(createdDoc);
87-
},
88-
});
89-
90-
return useCallback(
91-
(editor: DocsBlockNoteEditor, t: TFunction<'translation', undefined>) =>
92-
getInterlinkingMenuItems(
93-
editor,
94-
t,
95-
t('Links'),
96-
() =>
97-
currentDoc?.id &&
98-
createChildDoc({
99-
parentId: currentDoc.id,
100-
}),
101-
),
102-
[createChildDoc, currentDoc?.id],
103-
);
71+
return (
72+
editor: DocsBlockNoteEditor,
73+
t: TFunction<'translation', undefined>,
74+
) => getInterlinkinghMenuItems(editor, t, t('Links'), createChildDoc);
10475
};

src/frontend/apps/impress/src/features/docs/doc-editor/components/custom-inline-content/Interlinking/SearchPage.tsx

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@ import {
55
} from '@blocknote/core';
66
import { useBlockNoteEditor } from '@blocknote/react';
77
import { useEffect, useRef, useState } from 'react';
8+
import { useTranslation } from 'react-i18next';
89
import { css } from 'styled-components';
910

1011
import {
1112
Box,
1213
Card,
1314
Icon,
1415
QuickSearch,
16+
QuickSearchGroup,
1517
QuickSearchItemContent,
1618
Text,
1719
} from '@/components';
@@ -22,7 +24,12 @@ import {
2224
DocsStyleSchema,
2325
} from '@/docs/doc-editor';
2426
import FoundPageIcon from '@/docs/doc-editor/assets/doc-found.svg';
25-
import { useTrans } from '@/docs/doc-management';
27+
import AddPageIcon from '@/docs/doc-editor/assets/doc-plus.svg';
28+
import {
29+
useCreateChildDocTree,
30+
useDocStore,
31+
useTrans,
32+
} from '@/docs/doc-management';
2633
import { DocSearchSubPageContent, DocSearchTarget } from '@/docs/doc-search';
2734
import { useResponsiveStore } from '@/stores';
2835

@@ -64,6 +71,9 @@ export const SearchPage = ({
6471
DocsInlineContentSchema,
6572
DocsStyleSchema
6673
>();
74+
const { t } = useTranslation();
75+
const { currentDoc } = useDocStore();
76+
const createChildDoc = useCreateChildDocTree(currentDoc?.id);
6777
const inputRef = useRef<HTMLInputElement>(null);
6878
const [search, setSearch] = useState('');
6979
const { isDesktop } = useResponsiveStore();
@@ -248,6 +258,52 @@ export const SearchPage = ({
248258
/>
249259
)}
250260
/>
261+
<QuickSearchGroup
262+
group={{
263+
groupName: '',
264+
elements: [],
265+
endActions: [
266+
{
267+
onSelect: createChildDoc,
268+
content: (
269+
<Box
270+
$css={css`
271+
border-top: 1px solid
272+
var(--c--theme--colors--greyscale-200);
273+
`}
274+
$width="100%"
275+
>
276+
<Box
277+
$direction="row"
278+
$gap="0.4rem"
279+
$align="center"
280+
$padding={{
281+
vertical: '0.5rem',
282+
horizontal: '0.3rem',
283+
}}
284+
$css={css`
285+
&:hover {
286+
background-color: var(
287+
--c--theme--colors--greyscale-100
288+
);
289+
}
290+
`}
291+
>
292+
<AddPageIcon />
293+
<Text
294+
$size="14px"
295+
$color="var(--c--theme--colors--greyscale-1000)"
296+
contentEditable={false}
297+
>
298+
{t('New sub-doc')}
299+
</Text>
300+
</Box>
301+
</Box>
302+
),
303+
},
304+
],
305+
}}
306+
/>
251307
</Card>
252308
</QuickSearch>
253309
</Box>
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
export * from './useCollaboration';
22
export * from './useCopyDocLink';
3+
export * from './useCreateChildDocTree';
34
export * from './useDocUtils';
45
export * from './useIsCollaborativeEditable';
56
export * from './useTrans';
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import { useTreeContext } from '@gouvfr-lasuite/ui-kit';
2+
import { useRouter } from 'next/navigation';
3+
4+
import { useCreateChildDoc } from '../api';
5+
import { Doc } from '../types';
6+
7+
export const useCreateChildDocTree = (parentId?: string) => {
8+
const treeContext = useTreeContext<Doc>();
9+
const router = useRouter();
10+
11+
const { mutate: createChildDoc } = useCreateChildDoc({
12+
onSuccess: (createdDoc) => {
13+
const newDoc = {
14+
...createdDoc,
15+
children: [],
16+
childrenCount: 0,
17+
parentId: parentId ?? undefined,
18+
};
19+
treeContext?.treeData.addChild(parentId || null, newDoc);
20+
21+
router.push(`/docs/${newDoc.id}`);
22+
treeContext?.treeData.setSelectedNode(createdDoc);
23+
},
24+
});
25+
26+
return () => {
27+
if (!parentId) {
28+
return null;
29+
}
30+
31+
createChildDoc({
32+
parentId,
33+
});
34+
};
35+
};

0 commit comments

Comments
 (0)