Compare commits

...

7 Commits

Author SHA1 Message Date
virgile-deville faf38de099 📝(readme) add changelog entry
Added changelog entry so the pr passes the test
2025-02-23 11:48:54 +01:00
virgile-deville c120ad4b84 📝(readme) move front-end local run instructions
New comers should only see the main info.
I removed the special commands from the readme.
And moved them to the /docs/local.md
2025-02-21 15:21:21 +01:00
Manuel Raynaud ef8ee67553 ♻️(compose) set compose name in the docker-compose file
The helper bin/compose was using the option -p to set the compose
project name but this option is not used in the Makefile. This can lead
to different way to use the docker compose file definition with
different project name. In order to have a consistent name everywhere
and for everybody, we set the name in the docker compose file itself.
2025-02-20 10:32:37 +01:00
Anthony LC ad47fc2d60 (e2e) global setup authentication
Because of the parallelism of the tests,
the authentication setup was flaky. Sometimes
the tests would run before the authentication
was complete.
We change to a global setup instead of the
project dependency setup, it should be more
reliable.
We improved the waiting states of the authentication
setup.
2025-02-19 14:57:15 +01:00
Nathan Vasse 009f5d6ed4 ♻️(front) improve table pdf rendering
The previous way of rendering table was causing issues when tables
could not fit on one page. I then came accross this discussion
https://github.com/diegomura/react-pdf/issues/2343. The author
created a lib to improve the rendering of table, it's better, but
still not perfect maybe.
2025-02-19 13:58:29 +01:00
Nathan Vasse 64d0072c8d 🐛(front) improve text rendering in pdf
The rendered text had unwanted line breaks in middle of them.
It was because we were not using the appropriate Text component, the
one to be used in the one from react-pdf.
2025-02-18 17:01:58 +01:00
Anthony LC aefbc2e0b9 🛂(frontend) hide version restore button when reader
When you are a reader member, you have the right to
see the version but you cannot restore
them. So, we hide the restore button
when you are a reader.
2025-02-18 09:30:37 +01:00
13 changed files with 268 additions and 93 deletions
+10 -22
View File
@@ -6,14 +6,18 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0),
and this project adheres to
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## Changed
- 🛂(frontend) Restore version visibility #629
- 📝(doc) minor README.md formatting and wording enhancements
- ♻️Stop setting a default title on doc creation #634
- 📝(readme) remove front-end local run instructions local.md #651
## Fixed
- ♻️(frontend) improve table pdf rendering
## [2.2.0] - 2025-02-10
@@ -34,7 +38,6 @@ and this project adheres to
- 🐛(frontend) fix cursor breakline #609
- 🐛(frontend) fix style pdf export #609
## [2.1.0] - 2025-01-29
## Added
@@ -50,7 +53,7 @@ and this project adheres to
## Changed
- 💄(frontend) add abilities on doc row #581
- 💄(frontend) improve DocsGridItem responsive padding #582
- 💄(frontend) improve DocsGridItem responsive padding #582
- 🔧(backend) Bump maximum page size to 200 #516
- 📝(doc) Improve Read me #558
@@ -62,7 +65,6 @@ and this project adheres to
- 🔥(backend) remove "content" field from list serializer # 516
## [2.0.1] - 2025-01-17
## Fixed
@@ -117,12 +119,11 @@ and this project adheres to
- ⚡️(e2e) reduce flakiness on e2e tests #511
## Fixed
- 🐛(frontend) update doc editor height #481
- 💄(frontend) add doc search #485
## [1.9.0] - 2024-12-11
## Added
@@ -144,21 +145,18 @@ and this project adheres to
- 🐛(frontend) Fix hidden menu on Firefox #468
- 🐛(backend) fix sanitize problem IA #490
## [1.8.2] - 2024-11-28
## Changed
- ♻️(SW) change strategy html caching #460
## [1.8.1] - 2024-11-27
## Fixed
- 🐛(frontend) link not clickable and flickering firefox #457
## [1.8.0] - 2024-11-25
## Added
@@ -187,7 +185,6 @@ and this project adheres to
- 🐛(frontend) users have view access when revoked #387
- 🐛(frontend) fix placeholder editable when double clicks #454
## [1.7.0] - 2024-10-24
## Added
@@ -215,7 +212,6 @@ and this project adheres to
- 🔥(helm) remove infra related codes #366
## [1.6.0] - 2024-10-17
## Added
@@ -238,7 +234,6 @@ and this project adheres to
- 🐛(backend) fix nginx docker container #340
- 🐛(frontend) fix copy paste firefox #353
## [1.5.1] - 2024-10-10
## Fixed
@@ -273,7 +268,6 @@ and this project adheres to
- 🔧(backend) fix configuration to avoid different ssl warning #297
- 🐛(frontend) fix editor break line not working #302
## [1.4.0] - 2024-09-17
## Added
@@ -294,7 +288,6 @@ and this project adheres to
- 🐛(backend) Fix forcing ID when creating a document via API endpoint #234
- 🐛 Rebuild frontend dev container from makefile #248
## [1.3.0] - 2024-09-05
## Added
@@ -319,7 +312,6 @@ and this project adheres to
- 🔥(frontend) remove saving modal #213
## [1.2.1] - 2024-08-23
## Changed
@@ -327,7 +319,6 @@ and this project adheres to
- ♻️ Change ordering docs datagrid #195
- 🔥(helm) use scaleway email #194
## [1.2.0] - 2024-08-22
## Added
@@ -351,14 +342,14 @@ and this project adheres to
- ⚡️(CI) only e2e chrome mandatory #177
## Removed
- 🔥(helm) remove htaccess #181
- 🔥(helm) remove htaccess #181
## [1.1.0] - 2024-07-15
## Added
- 🤡(demo) generate dummy documents on dev users #120
- 🤡(demo) generate dummy documents on dev users #120
- ✨(frontend) create side modal component #134
- ✨(frontend) Doc grid actions (update / delete) #136
- ✨(frontend) Doc editor header information #137
@@ -369,12 +360,11 @@ and this project adheres to
- ♻️(frontend) create a doc from a modal #132
- ♻️(frontend) manage members from the share modal #140
## [1.0.0] - 2024-07-02
## Added
- 🛂(frontend) Manage the document's right (#75)
- 🛂(frontend) Manage the document's right (#75)
- ✨(frontend) Update document (#68)
- ✨(frontend) Remove document (#68)
- 🐳(docker) dockerize dev frontend (#63)
@@ -408,7 +398,6 @@ and this project adheres to
- 💚(CI) Remove trigger workflow on push tags on CI (#68)
- 🔥(frontend) Remove coming soon page (#121)
## [0.1.0] - 2024-05-24
## Added
@@ -416,7 +405,6 @@ and this project adheres to
- ✨(frontend) Coming Soon page (#67)
- 🚀 Impress, project to manage your documents easily and collaboratively.
[unreleased]: https://github.com/numerique-gouv/impress/compare/v2.2.0...main
[v2.2.0]: https://github.com/numerique-gouv/impress/releases/v2.2.0
[v2.1.0]: https://github.com/numerique-gouv/impress/releases/v2.1.0
+1 -21
View File
@@ -40,7 +40,7 @@ Docs is a collaborative text editor designed to address common challenges in kno
* 📚 Built-in wiki functionality to turn your team's collaborative work into organized knowledge `ETA 02/2025`
### Self-host
* 🚀 Easy to install, scalable and secure alternative to Notion, Outline or Confluence
* 🚀 Easy to install, scalable and secure alternative to Notion and Outline.
## Getting started 🔧
@@ -100,26 +100,6 @@ password: impress
$ make run
```
⚠️ For the frontend developer, it is often better to run the frontend in development mode locally.
To do so, install the frontend dependencies with the following command:
```shellscript
$ make frontend-development-install
```
And run the frontend locally in development mode with the following command:
```shellscript
$ make run-frontend-development
```
To start all the services, except the frontend container, you can use the following command:
```shellscript
$ make run-backend
```
**Adding content**
You can create a basic demo site by running:
+1 -3
View File
@@ -7,7 +7,6 @@ UNSET_USER=0
TERRAFORM_DIRECTORY="./env.d/terraform"
COMPOSE_FILE="${REPO_DIR}/docker-compose.yml"
COMPOSE_PROJECT="docs"
# _set_user: set (or unset) default user id used to run docker commands
@@ -40,9 +39,8 @@ function _set_user() {
# ARGS : docker compose command arguments
function _docker_compose() {
echo "🐳(compose) project: '${COMPOSE_PROJECT}' file: '${COMPOSE_FILE}'"
echo "🐳(compose) file: '${COMPOSE_FILE}'"
docker compose \
-p "${COMPOSE_PROJECT}" \
-f "${COMPOSE_FILE}" \
--project-directory "${REPO_DIR}" \
"$@"
+2
View File
@@ -1,3 +1,5 @@
name: docs
services:
postgresql:
image: postgres:16
+92
View File
@@ -0,0 +1,92 @@
# Run Docs locally
> ⚠️ Running Docs locally using the methods described below is for testing purposes only. It is based on building Docs using Minio as the S3 storage solution: if you want to use Minio for production deployment of Docs, you will need to comply with Minio's AGPL-3.0 licence.
**Prerequisite**
Make sure you have a recent version of Docker and [Docker Compose](https://docs.docker.com/compose/install) installed on your laptop:
```shellscript
$ docker -v
Docker version 20.10.2, build 2291f61
$ docker compose version
Docker Compose version v2.32.4
```
> ⚠️ You may need to run the following commands with sudo but this can be avoided by adding your user to the `docker` group.
**Project bootstrap**
The easiest way to start working on the project is to use GNU Make:
```shellscript
$ make bootstrap FLUSH_ARGS='--no-input'
```
This command builds the `app` container, installs dependencies, performs database migrations and compile translations. It's a good idea to use this command each time you are pulling code from the project repository to avoid dependency-related or migration-related issues.
Your Docker services should now be up and running 🎉
You can access to the project by going to <http://localhost:3000>.
You will be prompted to log in, the default credentials are:
```
username: impress
password: impress
```
📝 Note that if you need to run them afterwards, you can use the eponym Make rule:
```shellscript
$ make run
```
**Adding content**
You can create a basic demo site by running:
```shellscript
$ make demo
```
Finally, you can check all available Make rules using:
```shellscript
$ make help
```
**Django admin**
You can access the Django admin site at
<http://localhost:8071/admin>.
You first need to create a superuser account:
```shellscript
$ make superuser
```
## Front-end dev instructions
⚠️ For the frontend developer, it is often better to run the frontend in development mode locally.
To do so, install the frontend dependencies with the following command:
```shellscript
$ make frontend-development-install
```
And run the frontend locally in development mode with the following command:
```shellscript
$ make run-frontend-development
```
To start all the services, except the frontend container, you can use the following command:
```shellscript
$ make run-backend
```
@@ -1,27 +1,46 @@
import { test as setup } from '@playwright/test';
import { FullConfig, FullProject, chromium, expect } from '@playwright/test';
import { keyCloakSignIn } from './common';
setup('authenticate-chromium', async ({ page }) => {
await page.goto('/');
await keyCloakSignIn(page, 'chromium');
await page
.context()
.storageState({ path: `playwright/.auth/user-chromium.json` });
});
const saveStorageState = async (
browserConfig: FullProject<unknown, unknown>,
) => {
const browserName = browserConfig?.name || 'chromium';
setup('authenticate-webkit', async ({ page }) => {
await page.goto('/');
await keyCloakSignIn(page, 'webkit');
await page
.context()
.storageState({ path: `playwright/.auth/user-webkit.json` });
});
const { storageState, ...useConfig } = browserConfig?.use;
const browser = await chromium.launch();
const context = await browser.newContext(useConfig);
const page = await context.newPage();
setup('authenticate-firefox', async ({ page }) => {
await page.goto('/');
await keyCloakSignIn(page, 'firefox');
await page
.context()
.storageState({ path: `playwright/.auth/user-firefox.json` });
});
await page.goto('/', { waitUntil: 'networkidle' });
await page.content();
await expect(page.getByText('Docs').first()).toBeVisible();
await keyCloakSignIn(page, browserName);
await expect(
page.locator('header').first().getByRole('button', {
name: 'Logout',
}),
).toBeVisible();
await page.context().storageState({
path: storageState as string,
});
await browser.close();
};
async function globalSetup(config: FullConfig) {
/* eslint-disable @typescript-eslint/no-non-null-assertion */
const chromeConfig = config.projects.find((p) => p.name === 'chromium')!;
const firefoxConfig = config.projects.find((p) => p.name === 'firefox')!;
const webkitConfig = config.projects.find((p) => p.name === 'webkit')!;
/* eslint-enable @typescript-eslint/no-non-null-assertion */
await saveStorageState(chromeConfig);
await saveStorageState(webkitConfig);
await saveStorageState(firefoxConfig);
}
export default globalSetup;
+1 -5
View File
@@ -38,10 +38,9 @@ export default defineConfig({
timeout: 120 * 1000,
reuseExistingServer: true,
},
globalSetup: require.resolve('./__tests__/app-impress/auth.setup'),
/* Configure projects for major browsers */
projects: [
{ name: 'setup', testMatch: /.*\.setup\.ts/ },
{
name: 'chromium',
use: {
@@ -53,7 +52,6 @@ export default defineConfig({
permissions: ['clipboard-read', 'clipboard-write'],
},
},
dependencies: ['setup'],
},
{
name: 'webkit',
@@ -63,7 +61,6 @@ export default defineConfig({
timezoneId: 'Europe/Paris',
storageState: 'playwright/.auth/user-webkit.json',
},
dependencies: ['setup'],
},
{
name: 'firefox',
@@ -79,7 +76,6 @@ export default defineConfig({
},
},
},
dependencies: ['setup'],
},
],
});
+1
View File
@@ -15,6 +15,7 @@
"test:watch": "jest --watch"
},
"dependencies": {
"@ag-media/react-pdf-table": "2.0.1",
"@blocknote/core": "0.23.2",
"@blocknote/mantine": "0.23.2",
"@blocknote/react": "0.23.2",
@@ -15,7 +15,7 @@ import {
VariantType,
useToastProvider,
} from '@openfun/cunningham-react';
import { pdf } from '@react-pdf/renderer';
import { Text as PDFText, pdf } from '@react-pdf/renderer';
import { useMemo, useState } from 'react';
import { useTranslation } from 'react-i18next';
import { css } from 'styled-components';
@@ -27,6 +27,8 @@ import { Doc } from '@/features/docs/doc-management';
import { TemplatesOrdering, useTemplates } from '../api/useTemplates';
import { downloadFile, exportResolveFileUrl } from '../utils';
import { Table } from './blocks/Table';
enum DocDownloadFormat {
PDF = 'pdf',
DOCX = 'docx',
@@ -113,7 +115,8 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
? 1.5
: 1.17;
return (
<Text
<PDFText
key={block.id}
style={{
fontSize: fontSizeEM * FONT_SIZE * PIXELS_PER_POINT,
fontWeight: 700,
@@ -122,7 +125,7 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
}}
>
{exporter.transformInlineContent(block.content)}
</Text>
</PDFText>
);
},
paragraph: (block, exporter) => {
@@ -146,11 +149,14 @@ export const ModalExport = ({ onClose, doc }: ModalExportProps) => {
}
}
return (
<Text key={block.id}>
<PDFText key={block.id}>
{exporter.transformInlineContent(block.content)}
</Text>
</PDFText>
);
},
table: (block, transformer) => {
return <Table data={block.content} transformer={transformer} />;
},
},
},
{
@@ -0,0 +1,76 @@
import { TD, TH, TR, Table as TablePDF } from '@ag-media/react-pdf-table';
import {
DefaultBlockSchema,
Exporter,
InlineContentSchema,
StyleSchema,
TableContent,
} from '@blocknote/core';
import { View } from '@react-pdf/renderer';
import { ReactNode } from 'react';
export const Table = (props: {
data: TableContent<InlineContentSchema>;
transformer: Exporter<
DefaultBlockSchema,
InlineContentSchema,
StyleSchema,
unknown,
unknown,
unknown,
unknown
>;
}) => {
return (
<TablePDF>
{props.data.rows.map((row, index) => {
if (index === 0) {
return (
<TH key={index}>
{row.cells.map((cell, index) => {
// Make empty cells are rendered.
if (cell.length === 0) {
cell.push({
styles: {},
text: ' ',
type: 'text',
});
}
return (
<TD key={index}>
{props.transformer.transformInlineContent(cell)}
</TD>
);
})}
</TH>
);
}
return (
<TR key={index}>
{row.cells.map((cell, index) => {
// Make empty cells are rendered.
if (cell.length === 0) {
cell.push({
styles: {},
text: ' ',
type: 'text',
});
}
return (
<TD key={index}>
<View>
{
props.transformer.transformInlineContent(
cell,
) as ReactNode
}
</View>
</TD>
);
})}
</TR>
);
})}
</TablePDF>
);
};
@@ -36,8 +36,9 @@ export const ModalSelectVersion = ({
const { t } = useTranslation();
const [selectedVersionId, setSelectedVersionId] =
useState<Versions['version_id']>();
const canRestore = doc.abilities.partial_update;
const restoreModal = useModal();
return (
<>
<Modal
@@ -127,21 +128,23 @@ export const ModalSelectVersion = ({
selectedVersionId={selectedVersionId}
/>
</Box>
<Box
$padding="xs"
$css={css`
border-top: 1px solid var(--c--theme--colors--greyscale-200);
`}
>
<Button
fullWidth
disabled={!selectedVersionId}
onClick={restoreModal.open}
color="primary"
{canRestore && (
<Box
$padding="xs"
$css={css`
border-top: 1px solid var(--c--theme--colors--greyscale-200);
`}
>
{t('Restore')}
</Button>
</Box>
<Button
fullWidth
disabled={!selectedVersionId}
onClick={restoreModal.open}
color="primary"
>
{t('Restore')}
</Button>
</Box>
)}
</Box>
</Box>
</Modal>
@@ -0,0 +1,9 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// This file is used to declare the types for the @ag-media/react-pdf-table package
// This library does not export its types in the "exports" field in the package.json.
declare module '@ag-media/react-pdf-table' {
export const TD: React.FC<any>;
export const TH: React.FC<any>;
export const TR: React.FC<any>;
export const Table: React.FC<any>;
}
+5
View File
@@ -7,6 +7,11 @@
resolved "https://registry.yarnpkg.com/@adobe/css-tools/-/css-tools-4.4.1.tgz#2447a230bfe072c1659e6815129c03cf170710e3"
integrity sha512-12WGKBQzjUAI4ayyF4IAtfw2QR/IDoqk6jTddXDhtYTJF9ASmoE1zst7cVtP0aL/F1jUJL5r+JxKXKEgHNbEUQ==
"@ag-media/react-pdf-table@2.0.1":
version "2.0.1"
resolved "https://registry.yarnpkg.com/@ag-media/react-pdf-table/-/react-pdf-table-2.0.1.tgz#609e51992faed54bcf379a376442997c6bac53cc"
integrity sha512-UMNdGYAfuI6L1wLRziYmwcp/8I2JgbwX+PY7bHXGb2+P6MwgFJH8W71qZO1bxfxrmVUTP8YblQwl1PkXG2m6Rg==
"@ampproject/remapping@^2.2.0":
version "2.3.0"
resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.3.0.tgz#ed441b6fa600072520ce18b43d2c8cc8caecc7f4"