Implemented the logic to show 'Just now' instead
of '0 seconds ago' when the difference is under
one second.
Signed-off-by: buildwithricky <nwakezepatrick@gmail.com>
When going from one subdoc to another by example,
the broadcast store could have difficulty to resync.
This commit ensures that the broadcast store
cleans up and resets its state when rerendering.
It will stop as well triggering the action for
the current user avoiding potential unecessary
requests.
Add support for the `AWS_S3_SIGNATURE_VERSION` environment variable to
allow configuring S3 signature version for compatibility with
S3-compatible storage services like Linode Object Storage.
Fixes#1788
Signed-off-by: dtinth on MBP M1 <dtinth@spacet.me>
Added:
- ✨(frontend) integrate configurable Waffle
- ✨ Import of documents
- 🚨(CI) gives warning if theme not updated
- ✨(frontend) Add stat for Crisp
- ✨(auth) add silent login
- 🔧(project) add DJANGO_EMAIL_URL_APP environment variable
Changed:
- ♿(frontend) improve accessibility:
- ♿️(frontend) fix subdoc opening and emoji pick focus
- ✨(backend) add field for button label in email template
Fixed:
- ✅(e2e) fix e2e test for other browsers
- 🐛(export) fix export column NaN
- 🐛(frontend) add fallback for unsupported Blocknote
languages
- 🐛(frontend) fix emojipicker closing in tree
- 🐛(frontend) display children in favorite
- 🐛(frontend) preserve typed text after @ on escape
Removed:
- 🔥(project) remove all code related to template
Security:
- 🔒️(trivy) fix vulnerability about jaraco.context
We want to split the cache config between the app cache and the session
cache. In the app cache, the default one, we allow to configure a
prefix. By default this prefix is a fixed string so the cache will be
never revoked because it is changing but it allow every instance to
implement its own strategy like prefixing the keyx cache with a
timestamp.
To not impact session, the session cache is splitted in the settings.
Ui-kit expose now correctly the Marianne font.
We can use it now just by importing the font
from our css, no need to copy paste the font
in the public folder.
Not every project requires silent login.
This commit adds a new feature flag
FRONTEND_SILENT_LOGIN_ENABLED to enable or
disable silent login functionality.
Currently users already logged in to the SSO have to click on
the login button again to be connected.
This extra step should not be necessary.
This commit uses the "silent=true" parameter to the login
endpoint to avoid the extra step.
Most of Docs app is configured thanks to environment
variables, except the url in the email that
was from the django site table.
Now we can set it with DJANGO_EMAIL_URL_APP
environment variable to have a better consistency.
We keep the previous way to avoid breaking
changes.
During the export of tables to PDF, columns
with NaN widths were not handled correctly,
leading to export not exporting.
We now take in case NaN columnwidths.
We update the regressions tests to include
this kind of tables.
The max size and allowed extensions for document
import are now fetched from the application
configuration.
This ensures consistency across the app and
allows for easier updates to these
settings in the future.
Image and document uploaded were limited to 10MB.
For the conversion service, we allow up to 20MB.
For the dev and feature environment, we have to increase this value
accordingly.
Added Helm templates for docspec deployment and service to enable
document specification conversion in the Kubernetes environment.
Updated Tiltfile, compose.yml, and Helm values to
configure docspec integration alongside the
backend converter service for document import functionality.
Refactored converter services based on PR #1609 review comments:
- Renamed parameter to `data` across all convert methods for consistency
- Replaced recursive call with explicit sequential calls for readability
- Hardcoded CONVERSION_API_SECURE=True in Production class for security
- Removed unused YdocConverter import from viewsets.py
- Updated tests to match new error message wording
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
Added comprehensive tests covering DocSpec converter service,
converter orchestration, and document creation with file uploads.
Tests validate DOCX and Markdown conversion workflows, error
handling, service availability, and edge cases including empty
files and Unicode filenames.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
Add import document area with drag and drop
support in the docs grid component.
We can now import docx and and md files just
by dropping them into the designated area.
We are using the `react-dropzone` library to
handle the drag and drop functionality.
We can now import documents in formats .docx and .md.
To do so we added a new container "docspec", which
uses the docspec service to convert
these formats to Blocknote format.
More here: #1567#1569.
The template feature is removed.
Migration created to drop related tables.
Files modified:
- viewsets
- serializers
- models
- admin
- factories
- urls
- tests
- demo data
## Purpose
The email template is made with the idea that they link to a document.
This change allows to customize the label of the button (currently,
"Open") to allow for a different action verb. Additionally, the
'document_title' parameter is renamed to 'link_label' to reflect that it
can link to other things than documents.
## Proposal
- [x] Email template `template.mjml` updated as proposed
- [x] Method `send_email()` updated
- [x] Translations updated
We got a vulnerability report from Trivy about
jaraco.context package. It comes from setuptools.
setuptools does not seems used by the application.
We removed it.
In the tree view, if the emoji picker is opened
near the bottom of the viewport, it would
trigger an overflow that rerendered the treeview
and closed the picker immediately.
The root problem is the treeview that rerender
because of not stable props.
To fix this, we change 2 things:
- we use "fixed" position for the emoji picker
so it won't affect the document flow
- we adjust the position calculation logic, if
the picker does not have enough space below,
we position it above the icon instead.
We had a warning in the console about the
resizable panel component.
This commit fixes that warning by ensuring that the
size is never inferior to the minimum size.
We had a bug when user selected a language that is
not supported by BlockNote editor, the app
would crash.
If the language is not supported by BlockNote,
we now fallback Blocknote editor to English.
Integrate Waffle component based on LaGaufreV2
from @gouvfr-lasuite/ui-kit.
Waffle will be fully configurable via the app config,
allowing to be set through environment variables
and api-provided configuration.
In this test the comment is made using the "current" browser which can
be Chromium but can also be Firefox or Webkit.
This is why the test failed with other browsers.
Signed-off-by: Anto59290 <antonin59290@hotmail.com>
Since celery version 5.6.0 we have trouble with retrying tasks and it is
impactig the malware_detection workflow. We have to use version 5.5.3
while we found the issue.
Added:
- ✨(backend) add documents/all endpoint with descendants
- ✅(export) add PDF regression tests
- 📝(docs) Add language configuration documentation
- 🔒(helm) Set default security context
- ✨(backend) use langfuse to monitor AI actions
Changed:
- ♿(frontend) improve accessibility:
- ♿(frontend) make html export accessible to screen reader users
- ♿(frontend) add missing label and fix Axes errors to improve a11y
Fixed:
- ✅(backend) reduce flakiness on backend test
- 🐛(frontend) fix clickable main content regression
- 🐛(backend) fix TRASHBIN_CUTOFF_DAYS type error
- 💄(frontend) fix icon position in callout block
Security:
- 🔒️(backend) validate more strictly url used by cors-proxy endpoint
- 🔒️(frontend) fix props vulnerability in Interlinking
We were not properly sanitizing props passed to the
InterlinkingLinkInlineContent component, which could
lead to XSS attacks. This commit remove most of the
props and only keep the necessary ones.
Make sure the icon in the callout block is aligned to the top instead of
centered when we have multi-line content.
Signed-off-by: Anto59290 <antonin59290@hotmail.com>
We improved the export regression test PDF to
better cover edge case emoji.
PDF Binary comparison is different depending on the
browser used, we will only run this test on Chromium
to avoid having to maintain multiple sets of PDF
fixtures.
We want to monitor AI actions. For this we choose to use langfuse. As
this usage is optional, we load langfuse sdk only if settings are
configured. Also, the openai client from langfuse is a dropin
replacement of openai client, so we only have to change how openai is
imported.
The cors-proxy endpoint was allowing redirect when fetching the target
url. This can be usefull if an image url has changed but also dangerous
if an attacker wants to hide a SSRF behind a redirect.
When the content-type return by the targeted url is not an image, the
endpoint was returning a 415 status code. We don't want to provide this
info anymore avoid disclosing information an attacker can use.
The cors-proxy endpoint allow to download images host externally without
being blocked by cors headers. The response is filter on the return
content-type to avoid disclosure and the usage of this endpoint as the
proxy used by attacker. We want to restrict the usage of this endpoint
by filtering on non legit ips used. This filter avoid exploitation of
Server Side Request Forgery (SSRF).
In order to be able to deploy this in a restricted k8s cluster, we set
this default security context.
We set it as default because it doesn't change the way the app runs.
So it is better to be more secured by default.
Signed-off-by: Pierre Ozoux Krebber <pierre@ozoux.net>
When all the backend authentication has been moved in the django-lasuite
library, we kept the tests to ensure that the mirgration was successful
and we didn't miss something during the transition. Now this tests are
managed in the django-lasuite library and should be maintained in it,
not in docs.
In one test related to the Document::restore function, one more query is
made. Probably a cache issue fixed in django-treebeard 4.8.0. When
updating the numchild parent, one more query is made to fetch in
database the parent document, this was not made before.
Add comprehensive guide explaining how to override LANGUAGES settings
using the DJANGO_LANGUAGES environment variable. Documentation includes:
- Default language configuration
- Environment variable format and examples
- Configuration for development, production, and Docker Compose
- Complete list of 15 available languages with translation files
- Language code formatting guidelines
- Testing and troubleshooting sections
Make sure the full is never John for the first user in order to make
sure we always have only 2 users (as the search is performed on both the
email and the full name).
Fixes#1765
Signed-off-by: Anto59290 <antonin59290@hotmail.com>
Heading 4 5 6 in PDF were not correctly
mapped to their corresponding styles in the
exported document.
The new export is now different than the regression
pdf, we need to update the regression PDF to match
the new correct export.
The regression test is asserting most of the
blocks of the editor, we can remove some redundant
tests.
We improved as well the odt and docx tests by
overriding as well the document content like for pdf,
it will assert more blocks and have less code
to maintain.
To avoid regression issues in PDF export
functionality, this commit introduces end-to-end
tests that compare exported PDFs against
known good reference files.
We compare the PDF on most of the blocks
that the editor supports.
If during a Blocknote release or pull request
there are intentional changes, the reference
files would need to be updated accordingly.
It can be done by uncommenting the line
in the test that saves the newly generated
PDF to the assets folder.
We improved the svg width calculation when the
width attribute is undefined by trying to use
the style attribute before falling back to a
default value.
External dashboards need to find the latest updated documents across
the entire hierarchy. Currently this requires many API calls to
/documents/ and /documents/{id}/children for each level.
This endpoint allows retrieving all accessible documents in a single
request, enabling dashboards to efficiently display recently changed
documents regardless of their position in the hierarchy.
Signed-off-by: ChristopherSpelt <christopherspelt@icloud.com>
Added:
- ✨(helm) redirecting system
- 📱(frontend) add comments for smaller device
- ✨(project) add custom js support via config
Changed:
- 🥅(frontend) intercept 401 error on GET threads
- 🦺(frontend) check content type pdf on PdfBlock
- ✈️(frontend) pause Posthog when offline
Fixed:
- 🐛(frontend) fix tables deletion
- 🐛(frontend) fix children not display when first resize
We have some issues with mobiles and the formatting
toolbar reopening after adding a comment, so we
restore the cursor position.
By restoring the cursor position at the head of
the selection, it will automatically close the
formatting toolbar.
Posthog keeps trying to send events when the user
is offline, causing the network request queue to fill up
and slowing down the app. This commit pauses Posthog
when the user is offline and resumes it when back online.
Pdfblock was quite permissive on the content type
it was accepting. Now it checks that the content
type is exactly 'application/pdf' before rendering
the PDF viewer.
Bump to BlockNote 0.45.0 to get the latest
features and fixes.
This release includes the fix for the table
deletion that breaks the editor when
deleting tables.
Passing the Next 16 will need more work to be compatible
with our application. We will do this upgrade later
in a dedicated PR.
We add it in the renovate.json to avoid having Renovate
trying to upgrade it again.
Create a new Helm template for ingress redirects
and update the values.yaml file accordingly.
We will be able to manage ingress redirects
through Helm charts easily.
To be intercepted by ingress redirects, we need
to redirect using window.location instead of
using Next.js router. The Next.js router does not
trigger a full page reload, so the ingress
redirect logic is not executed.
Added:
- ✨(backend) allow to create a new user in a marketing system
- ✨(backend) add async indexation of documents on save
(or access save)
- ✨(backend) add debounce mechanism to limit indexation jobs
- ✨(api) add API route to search for indexed documents in Find
- 🥅(frontend) add boundary error page
Changed:
- 🛂(backend) stop throttling collaboration servers
- 🚸(backend) use unaccented full name for user search
- 🌐(backend) internationalize demo
- ♿(frontend) improve accessibility:
- ♿️Improve keyboard accessibility for the document tree
Fixed:
- 🐛(frontend) paste content with comments from another document
- 🐛(frontend) Select text + Go back one page crash the app
We switching from one version to the other, depending on
the blocks inside, the version editor could
crash due to conflicts between the different versions.
We now reset the previous content
when switching version to avoid these conflicts.
Add a custom error page to handle unexpected errors
gracefully. This page provides users with options
to navigate back to the home page or refresh
the current page, enhancing the overall user
experience during error scenarios.
It is quite hard to test this page, it cannot
be trigger in development mode, we have to build
the app and have a real error in production to
see it.
adds f2 shortcut to open options menu in sub-documents
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(frontend) adds f2 shortcut using a fakenode since it's outside the treeview
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(frontend) add sr-only instructions with aria-describedby links
improves screen reader support with contextual accessibility guidance
Signed-off-by: Cyril <c.gromoff@gmail.com>
✅(frontend) add e2e test to check focus behavior with F2 shortcut
ensures F2 correctly focuses the expected UI element
Signed-off-by: Cyril <c.gromoff@gmail.com>
Disable OIDC_STORE_ACCESS_TOKEN & OIDC_STORE_REFRESH_TOKEN as default
to prevent authentication issues when the Find service is not used.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
As we filter the empty documents from the batch during indexing some batches
can be empty and cause an error. Now they are ignored.
Add --batch-size argument to the index command.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Reduce the number of Find API calls by grouping all the latest changes
for indexation : send all the documents updated or deleted since the
triggering of the task.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Set SEARCH_INDEXER_CLASS=None as default configuration for dev.
Rename docker network 'lasuite-net' as 'lasuite' to match with Drive
configuration.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Keep ordering by score from Find API on search/ results and
fallback search still uses "-update_at" ordering as default
Refactor pagination to work with a list instead of a queryset
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Replace indexer_debounce_lock|release functions by indexer_throttle_acquire()
Instead of mutex-like mechanism, simply set a flag in cache for an amount of
time that prevents any other task creation.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Rename FindDocumentIndexer as SearchIndexer
Rename FindDocumentSerializer as SearchDocumentSerializer
Rename package core.tasks.find as core.task.search
Remove logs on http errors in SearchIndexer
Factorise some code in search API view.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Add nginx with 'nginx' alias to the 'lasuite-net' network (keycloak calls)
Add celery-dev to the 'lasuite-net' network (Find API calls in jobs)
Set app-dev alias as 'impress' in the 'lasuite-net' network
Add indexer configuration in common settings
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Filter deleted documents from visited ones.
Set default ordering to the Find API search call (-updated_at)
BaseDocumentIndexer.search now returns a list of document ids instead of models.
Do not call the indexer in signals when SEARCH_INDEXER_CLASS is not defined
or properly configured.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
New SEARCH_INDEXER_CLASS setting to define the indexer service class.
Raise ImpoperlyConfigured errors instead of RuntimeError in index service.
Signed-off-by: Fabre Florian <ffabre@hybird.org>
On document content or permission changes, start a celery job that will call the
indexation API of the app "Find".
Signed-off-by: Fabre Florian <ffabre@hybird.org>
Search in Docs relies on an external project like "La Suite Find".
We need to declare a common external network in order to connect to
the search app and index our documents.
We observe some throttling pick here and there.
We observed that when the collaboration has a
problem, it is retrying to connect, leading to more
requests to the django backend. At one point, the
throttling is reached and the user would not
be able to use the application anymore.
Now when the request comes from a collaboration
server, we do not throttle it anymore.
The recent update of Blocknote brokes a test
because a element was not easily accessible anymore.
We improved the CalloutBlock to be able to
be closed when "escape" is pressed, we improve
the positionning of the EmojiPicker too.
WebSocketStatus.Connected does not mean
we are totally connected because authentication
can still be in progress and failed.
So we will use the event onAuthenticated to assert
that we are fully connected.
We bump the blocknote dependencies to version
0.44.2 to incorporate the latest features
and bug fixes.
It seems to fix an issue with Titap, when the text
was selected and the user clicked
on the Go Back button of the browser, the
application was crashing.
"[tiptap error]: The editor view is not available.
Cannot access view['dom']. The editor may not be
mounted yet."
When pasting comments, the data-bn-thread-id
attribute is present in the clipboard data.
This indicates that the pasted content contains comments.
But if the content with comments comes from another
document, it will create orphaned comments that
are not linked to this document and create errors.
To avoid this, we refresh the threads to ensure
that only comments relevant to the current document
are displayed.
This allows the demo to generate user and filenames with other locales
than English, for all languages defined in the project's settings.
In particular, it allows the generation of accented names, which were
previously missing.
The given_name and usual_name is not configured in the oidc scopes. When
a user connect to docs with the dev and feature configuration, we don't
have this informations.
We have the user full name through OIDC in the database, but the search only
used the email field.
This change allows to search for a user by their first and/or
last name (fix#929).
Given that user names are more likely than emails to include diacritics, it
unaccents both the query and the database entry for search (fix#1091).
It also unaccents for email so that internationalized domain names are
managed whether or not the accent is included in the search.
An unaccented gin index is added on users full_name an email fields.
Using a manual migration because a wrapper around unaccent is necessary
to make it IMMUTABLE (cf.
https://stackoverflow.com/questions/9063402/ )
We want to create a new user in a marketing system to create a dedicated
onboarding for each of them. The marketing service is implemented in the
django-lasuite library and it is possible to pick the backend we want
or implement a new one following the documentation on this library.
When resizing the window and crossing the desktop
breakpoint, the editor was unmounted. It could
lead to loss of data if there were unsaved changes,
and tiptap crash if the toolbar was used while the
editor was unmounted.
It was caused by the ResizableLeftPanel component
which was rerendering the editor.
We now keep the editor mounted when resizing
the window, by keeping the ResizableLeftPanel
component rendered but setting its size to 0
and disabling the resize handle.
When zooming in and out quickly, the editor
instance may not be fully mounted, leading to
errors when accessing its document. This commit
adds checks to ensure the editor and its view
are mounted before attempting to access the
document, preventing potential runtime errors.
dangerouslySetInnerHTML were introduced to quickly
render translated strings containing HTML,
but they can lead to security vulnerabilities
if not handled properly.
Better to use React components to ensure safety.
Improve the comments feature to reduce annoyance:
- gives focus on input when opening comment threads
- hide comment button when mobile view
- improve contrast of overline commented text
- remove thread if last comment deleted
- scroll to bottom thread when adding new comment
We now include a CSS style file in the exported
ZIP archive. This file contains styles that
enhance the appearance of the exported HTML
document when viewed in a web browser to look
more like the original document.
The / location is not trying the $uri/index.html file. We should try
this instad of $uri/ because when a new static page is added, we always
have this pattern.
add SkipToContent component to meet RGAA skiplink requirement
Signed-off-by: Cyril <c.gromoff@gmail.com>
✅(frontend) add e2e test for skiplink and fix broken accessibility test
ensures skiplink behavior is tested and stabilizes a failing accessibility test
Signed-off-by: Cyril <c.gromoff@gmail.com>
Added:
- ✨ Add comments feature to the editor
- ✨(backend) Comments on text editor
- ✨(frontend) link to create new doc
Changed:
- ⚡️(sw) stop to cache external resources likes videos
- 💥(frontend) upgrade to ui-kit v2
- ⚡️(frontend) improve perf on upload and table of contents
- ♿(frontend) improve accessibility:
- ♿(frontend) improve share modal button accessibility
- ♿(frontend) improve screen reader support in DocShare modal
Fixed:
- 🐛(frontend) fix toolbar not activated when reader
- 🐛(frontend) preserve left panel width on window resize
- 🐛(frontend) prevent duplicate as first character in title
IndexDB need a integer versioning when upgrading
the database, it has to be incremental.
Before the fix, version 4.0.0 would give 400, when
3.10.0 would give 3100. That would cause an error
and the database would be destroyed then recreated.
We improve the way we compute the version number
to ensure it is always incremental, avoiding such
issues.
On the release pull request workflows, we sometimes
face issues with disk space. We clean up some space
before starting Docker services or after finishing
to build images to avoid these issues.
When migrating to the new design system, some
colors and style issues were identified.
This commit addresses these issues by updating
the styles to align with the new design guidelines,
ensuring a consistent and visually appealing
user experience.
The table of contents was displayed even when there
were no headings in the document. It was
not the expected behavior.
We now ensure that the TOC is only shown
when there are headings present, we added a test
to verify this behavior.
Some compatibility issues were causing yarn to add
resolutions, they are no longer necessary, we can
remove them.
We pin as well to Next 15, passing to Next 16 will
require significant code changes, let's do that
in a dedicated PR.
We notices that `context.getChanges` was very
greedy, on a large document with multiple
users collaborating, it caused performance issues.
We change the way that we track a upload by
listening onUploadEnd event instead of tracking
all changes in the document.
When a doc opens, we check if there are any ongoing
uploads and resume them.
We fix as well a race condition that could happen
when multiple collaborators were on a document
during an upload.
- the Table of Contents stickiness now covers the
full height of the viewport, before it was limited to
100vh
- we listen the scroll to highlight the heading
in the Table of Contents only when the Table of Contents
is open
- We debounce the editor change to avoid excessive updates
to the Table of Contents
Depend the theme, you can have different Docs icons
in the header.
A customization was already possible from the
theme customization file, but now it is as
well possible to override the icon from the theme
itself, making it easier to manage different themes
with different icons.
We change the theme customization variable name
to "icon" instead of "logo", "logo" was already
used for the main logo of the application inside
the theme configuration.
Upgrade Docs to Ui-Kit v2 and apply new color
scheme from LaSuite design system.
This commit will probably create breaking changes if
user has custom styles applied to their docs.
Some videos from external sources can be very
large and slow to cache. To improve performance, we
decided to stop caching these resources in the
service worker.
We will cache only images and fonts from external
sources.
The videos will maybe not be available when offline
mode.
When user was a reader of the document, the toolbar
of the BlockNote editor was not activated,
making it impossible to download resources like images.
We add the toolbar even in viewer mode.
We block as well automatic document mutation
from custom blocks when the editor is in viewer mode
to avoid unwanted modifications.
In the UserLightSerializer we were fallbacking on a strategy to never
have a full_name or short_name empty. We use the part of the email
befire the @. We are doing the same thing now in the main
UserSerializer.
We extracted the UserAvatar component from the
doc-share feature and integrated it into
the users feature. It will be used in the
thread comments feature as well.
This commit add the CRUD part to manage comment lifeycle. Permissions
are relying on the Document and Comment abilities. Comment viewset
depends on the Document route and is added to the
document_related_router. Dedicated serializer and permission are
created.
In order to store the comments on a document, we created a new model
Comment. User is nullable because anonymous users can comment a Document
is this one is public with a link_role commentator.
Added:
- ✨(frontend) enable ODT export for documents
- ✨(frontend) improve mobile UX by showing subdocs count
Changed:
- ♻️(frontend) preserve @ character when esc is pressed
after typing it
- ♻️(frontend) make summary button fixed to remain visible
during scroll
- ♻️(frontend) pdf embed use full width
Fixed:
- ♿(frontend) improve accessibility:
- ♿(frontend) improve ARIA in doc grid and editor
for a11y
- ♿(frontend) improve accessibility and styling
of summary table
- ♿(frontend) add focus trap and enter key support
to remove doc modal
- 🐛(docx) fix image overflow by limiting width to
600px during export
- 🐛(frontend) fix fallback translations with Trans
- 🐛(pdf) fix table cell alignment issue in exported
documents
- 🐛(pdf) preserve image aspect ratio in PDF export
We were pinned to a specific package registry
coming from a pull request, the new version is now
published to npm, so we can use the version from there.
A complete API was able to manage templates lifecycle, from the creation
to the deletion and managing accesses on them. This API is not used by
the frontend application, is not finished. A connected user can interact
with this API and lead to unwanted behavior in the interface. Refering
ot issue #1222 templates can maybe totaly remove in the future. While
it's here and used, we only keep list and retrive endpoints. The
template management can still be done in the admin interface.
We have a mounting issue with the Blocknote
version 0.42.1. To not wait for the next Blocknote
release, we pin the Blocknote packages
to a specific pull request version.
We upgraded Blocknote to version 0.42.1 to benefit
from the latest features and bug fixes.
There is some compatibility issues with
tiptap extensions, so we had to pin tiptap
to "3.10.2" to ensure everything works smoothly.
There is as well some issues with prosemirror,
we pinned the problematic packages.
The fallback of the Trans component didn't work
anymore after upgrade to 16.2.3 of react-i18next.
Upgrading to 16.3.3 fixed the issue.
We added a test to cover this case.
We disable roles that the current user is not allowed
to assign when sharing a document. This prevents
users from selecting roles they cannot actually
assign, improving the user experience and reducing
confusion.
Like in other abilities, we compute a set_role_to property on the
abilities. This set_role_to contains all the roles lower or equal than
the current user role. We rely on this propoerty to validate the accept
endpoint and it will be used by the front allpication to built the role
select list.
We check that the role set in a ask_for_access is not higher than the
user's role accepting the request. We prevent case where ad min will
grant a user owner in order to take control of the document. Only owner
can accept an owner role.
provides ODT export with support for callout, upload, interlinking and tests
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(frontend) add image and interlinking support for odt export
Added image mapping with SVG conversion and clickable document links.
Signed-off-by: Cyril <c.gromoff@gmail.com>
✅(e2e) add e2e tests for odt export and interlinking features
covers odt document export and cross-section interlinking use cases
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(odt) add generic helper and style callout block for odt export
create odtRegisterParagraphStyleForBlock and apply background/padding styles
Signed-off-by: Cyril <c.gromoff@gmail.com>
Added
- ✨(frontend) create skeleton component for DocEditor
- ✨(frontend) add an EmojiPicker in the document
tree and title
- ✨(frontend) ajustable left panel
Changed:
- ♻️(frontend) adapt custom blocks to new implementation
- ♻️(backend) increase user short_name field length
- 🚸(frontend) separate viewers from editors
Fixed:
- 🐛(frontend) fix duplicate document entries in grid
- 🐛(backend) fix trashbin list
- ♿(frontend) improve accessibility:
- ♿(frontend) remove empty alt on logo due to Axe
a11y error
- 🐛(backend) fix s3 version_id validation
- 🐛(frontend) retry check media status after page reload
- 🐛(frontend) fix Interlinking memory leak
- 🐛(frontend) button new doc UI fix
- 🐛(frontend) interlinking UI fix
When receiving a 401 error, we should set the
auth query data to null, not to an object
with user: null and authenticated: false.
This ensures that components relying on the
auth state can correctly interpret the
unauthenticated status.
With time some visual inconsistencies have crept
into the DropButton and Icon component.
This commit aims to harmonize the appearance
with the design system.
When doing collaborative editing, doc?.title might
be out of sync for other users when updated by
another user.
This causes the useEffect to run repeatedly,
causing an infinite loop of updates.
We now trigger the effect only when doc?.title changes,
not when the customInlineContent changes.
We are now totally separating the viewers with
the editors. We will not load the provider
when we are in viewer mode, meaning the
viewers will not be aware of other users and
will not show their cursors anymore.
We still get the document updates in real-time.
We move some components related to doc versioning
into the doc-versioning feature folder to have a
better separation of concerns.
We don't need a provider for the doc versioning components
since they will receive the doc data directly via
a request.
Depend the month the test could fail if the current
month has 30 or 31 days, so change 30 to 35 to be sure
that it will always be at least 1 month ago.
Previous refactoring removed the retry logic for
checking media status after a page reload.
This commit reintroduces that functionality
to ensure uploads are properly processed even after
a page reload. We improve the test coverage
to validate this behavior.
The regex used on the version_detail endpoint path is not fully
compatible with the S3 spec. In the S3 specs, Version IDs are Unicode,
UTF-8 encoded, URL-ready, opaque strings that are no more than 1,024
bytes long. We don't accept all unicode characters but enough to be
compliant.
The EmojiPicker component now displays an overlay
when opened, it fixes an issue when multiple pickers
are present on the same page and we click on one of them,
the others were not closing.
The tests e2e highlighted a problem where content
was lost during synchronization. This bug
started to occurs after upgrading Blocknote to
0.41.1 version.
It seems to happen only when the initial document
is empty and 2 users are collaborating, so before
the first minute.
We now initialize the editor only when the y-doc
has attempted to sync. This should ensure that
all updates are applied before the editor
is initialized.
When we open the share modal, the requests were
then in cache, if other users where interacting
with the share settings in parallel,
we would not see the changes until the cache expired.
We now force a fresh fetch of the data when opening
the share modal, it ensures we always have the
latest data when opening the modal.
Move the `useUpdateDocLink` hook from the
`doc-management` feature to the `doc-share` feature
to better align with its functionality related
to document sharing.
Last release of Blocknote introduced breaking
changes for custom blocks.
We adapted our custom blocks to the new
implementation.
"code-block" is considered as a block now, we
update the way to import and use it.
The custom blocks should be now more tiptap friendly.
Recent upgrade of @tanstack/react-query to
version >5.90 introduced a breaking change in the
onSuccess and onError callback signatures for
the useMutation hook.
The context parameter has been replaced with an
onMutateResult parameter, which provides
information about the result of the
onMutate callback.
The user's short_name field length was set to 20. This is not enought
and we have some users who cannot register because of that. We changed
this length to a higher one, 100, like the full_name.
mainlayout and leftpanel updated with resizable panel saved in localstorage
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(frontend) show full nested doc names with horizontal scroll support
horizontal overflow enabled and opacity used for sticky actions visibility
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(frontend) show full nested doc names with horizontal scroll support
horizontal overflow enabled and opacity used for sticky actions visibility
Signed-off-by: Cyril <c.gromoff@gmail.com>
✨(frontend) add resizable-panels lib also used in our shared ui kit
needed for adaptable ui consistent with our shared ui kit components
Signed-off-by: Cyril <c.gromoff@gmail.com>
We recently upgraded to Eslint v9, it seems that
it is missing some rules that we had previously.
We add them back:
- @typescript-eslint/no-inferrable-types
- @typescript-eslint/no-floating-promises
- Because of parallel test execution, some tests
were flaky when using goToGridDoc, the title
changed between the time we got the document list
and the time we clicked on the document.
- Improve addChild function.
The tests e2e were failing sometimes because
the documents list was containing duplicates.
This was happening when multiple users were
modifying the documents list (creation, update, ...).
We now deduplicate documents by their ID
before displaying them.
When a new service worker is installed, the page
was reloaded to ensure the new service worker took
control, it is not a big issue in normal browsing mode
because the service worker is only updated once in a
while (every release).
However, in incognito mode, the service worker has to be
re-registered on each new session, which means that
the page was reloading each time the user opened a
new incognito window, creating a bad user experience.
We now take in consideration the case where the
service-worker is installed for the first time, and don't
reload if it is this case.
The document change admin page is unusable. The django treebeard library
can change the form used by one provided but this one is really slow.
And it is collapsing the configuration made with the other fields and
readonly fields declared on the DocumentAdmin class. In a first time we
remove the form usage, it seems useless. Later we have to provide more
information on this admin page.
An invitation can be updated to change its role. The front use a PATCH
sending only the changed role, so the email is missing in the
InivtationSerializer.validate method. We have to check first if an email
is present before working on it.
The trashbin endpoint is slow. To filter documents the user has owner
access, we use a subquery to compute the roles and then filter on this
subquery. This is very slow. To improve it, we use the same way to
filter children used in the tree endpoint. First we look for all highest
ancestors the user has access on with the owner role. Then we create one
queryset filtering on all the docs starting by the given path and are
deleted.
Added:
- ✨(frontend) add pdf block to the editor
- ✨List and restore deleted docs
Changed:
- ♻️(frontend) Refactor Auth component for improved redirection logic
- ♻️(frontend) replace Arial font-family with token font
- ♿(frontend) improve accessibility:
- ♿(frontend) enable enter key to open documentss
- ♿(frontend) improve modal a11y: structure, labels, title
- ♿improve NVDA navigation in DocShareModal
- ♿ improve accessibility by adding landmark roles to layout
- ♿ add document visible in list and openable via enter key
- ♿ add pdf outline property to enable bookmarks display
- ♿ hide decorative icons from assistive tech with aria-hidden
- ♿ fix rgaa 1.9.1: convert to figure/figcaption structure
- ♿ remove redundant aria-label to avoid over-accessibility
- ♿ remove redundant aria-label on hidden icons and update tests
- ♿ improve semantic structure and aria roles of leftpanel
- ♿ add default background to left panel for better accessibility
- ♿ restyle checked checkboxes: removing strikethrough
- ♿ add h1 for SR on 40X pages and remove alt texts
- ♿ update labels and shared document icon accessibility
- 🍱(frontend) Fonts GDPR compliants
- ♻️(service-worker) improve SW registration and update handling
Fixed:
- 🐛(backend) duplicate sub docs as root for reader users
- ⚗️(service-worker) remove index from cache first strategy
- 🐛(frontend) fix 404 page when reload 403 page
- 🐛(frontend) fix legacy role computation
- 🛂(frontend) block editing title when not allowed
- 🐛(frontend) scroll back to top when navigate to a document
- 🐛(frontend) fix export pdf emoji problem
- 🐛(frontend) fix attachment download filename
- 🐛(frontend) exclude h4-h6 headings from table of contents
- 🔒(frontend) prevent readers from changing callout emoji
- 🐛(frontend) fix overlapping placeholders in multi-column layout
- 🐛(backend) filter invitation with case insensitive email
- 🐛(frontend) reduce no access image size from 450 to 300
- 🐛(frontend) preserve interlink style on drag-and-drop in editor
- ✨(frontend) load docs logo from public folder via url
- 🔧(keycloak) Fix https required issue in dev mode
To not create a breaking change, the logo in the
theme customization is now optional, meaning that
if no logo is provided, the default logo will be used.
We add some documentation about this feature.
The document grid was showing a double scrollbar.
It was due to the sr-only class having a width and
height of 1px.
We changed it to 0px, it is now fixed.
A circular dependency was introduced in the previous
commit.
This commit resolves the circular dependency by
refactoring the code to remove the circular reference.
We want to improve the accessibility of our BoxButton
component by adding a theme focus visible style.
This will help users who navigate using the
keyboard to easily identify which button is currently
focused.
To do so we have to move some theme styles to
the Box component to be able to use them in
BoxButton.
Whe the doc is deleted, the doc page is a bit
different, we have to adapt the doc header
to add some information and actions that
are relevant for a deleted doc.
The tree endpoint will now return a result only for owners. For other
users the endpoint still returns a 403. Also, the endpoint does look for
ancestors anymore, it only stay on the current document.
The abilities for a deleted document were too open. We want to restrict
them. Only the restore, retrieve and tree is allowed. The tree method
will need some modifications to get the right informations.
In development mode, we will reduce the cache timeout
for theme customization to 15 seconds.
This change allows developers to see updates
to theme settings more quickly without needing
to clear the cache manually.
It is apparently a bad practice to add the version
number to the service worker file name.
This prevents the browser from properly updating
the service worker when a new version is available.
We improve the update handling by a more usual
pattern.
The app build can sometimes fail because stylelint
linter warns about css font files in
public/assets/fonts.
We do not need to lint these files as they are
third-party files.
The label preview will deploy a full environment. This environment is
accessible using a specific url. This commit will publish a comment with
the good url.
The certifi ca certificate is now stored under a static path
(/cert/cacert.pem) to avoid issues when python is upgraded and the path
to the certificate changes.
When a user was searching for an email in the share modal,
the search was case sensitive, so we were proposing
to send an invitation to a new user when in
fact the user was already registered.
The search is now case insensitive, so the only
choice is to add the existing user in the share list.
A user can be invited and no control is made on the email case. Then,
when a new user is created, we are looking if there are pending
invitation and the lookup used is case sensitive. We change it using
__iexact which is case insensitive.
We now use exported emoji from emoji-datasource-apple
package instead of relying on a CDN.
During a build or dev command, the emoji images
are copied from node_modules to the public assets
folder. They are not versionned.
We now use Marianne font from @gouvfr-lasuite/ui-kit
package instead of a versionned local copies.
This ensures we always use the latest version of
the font.
During a build or dev command, Marianne font files
are copied from node_modules to the public assets
folder. They can stop being versionned.
## Purpose
To move a doc you have to be at least admin of the destination doc.
It was written editor in the alert banner.
## Proposal
Change editor for administrator
## External contributions
Thank you for your contribution! 🎉
Please ensure the following items are checked before submitting your
pull request:
- [x] I have read and followed the [contributing
guidelines](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md)
- [x] I have read and agreed to the [Code of
Conduct](https://github.com/suitenumerique/docs/blob/main/CODE_OF_CONDUCT.md)
- [x] I have signed off my commits with `git commit --signoff` (DCO
compliance)
- [x] I have signed my commits with my SSH or GPG key (`git commit -S`)
- [x] My commit messages follow the required format: `<gitmoji>(type)
title description`
- [ ] I have added a changelog entry under `## [Unreleased]` section (if
noticeable change)
- [ ] I have added corresponding tests for new features or bug fixes (if
applicable)
Signed-off-by: virgile-deville <virgile.deville@beta.gouv.fr>
We had a case where the title input was editable
even when the user did not have the right to
edit it because of websocket problem during
collaboration. We fixed this issue by checking
the collaboration status before allowing the
edition of the title.
The way we were handling the antivirus upload loader
was not optimal, it didn't work well with the pdf
embed block. We created a dedicated upload loader
block, it will replace the previous implementation,
it is more Blocknote idiomatic and will work
better with any type of upload files.
When navigating to a new document, the scroll
position was preserved. This commit changes this
behavior to scroll back to the top of
the page when navigating to a new document.
In some components, the Arial font was still used
because of a centering problem.
We removed all instances of Arial and replaced them
with the current font token, the centering problems
were fixed by adding "contain: content;" to the css.
The link-configuration endpoint has now a strict
validation schema about the combination of
link_reach and link_role.
We need to adapt our types
frontend side to reflect that.
When a document was restricted, the link role could
be updated from "link-configuration" and gives a
200 response, but the change did not
have any effect because of a restriction in
LinkReachChoices.
We added a validation step to ensure that the
link role can only be updated if the document
is not restricted.
Some users reported that the app was giving a
blank page, it seems to happens often after a
release. It could be due to the fact that
the service worker is caching the index.html
file and not updating it properly after a new release.
We remove the index from the cache first strategy
to avoid this kind of issue. We set as well
the default handler with the "StaleWhileRevalidate"
strategy to force the cache to be updated in
the background.
When the provider reports a lost connection,
we invalidate the doc query to refetch the document
data.
This ensures that if a user has lost is rights
to access a document, he will be redirected
to a 403 page without needing to refresh the page.
When users were reloading a 403 page, they were
redirected to the 404 page because of Nextjs
routing mechanism. This commit fixes this issue by
removing the 403 page from the pages directory
and creating a component that is used directly
in the layout when a 403 error is detected.
Before the subpages feature, the user_role was
computed thanks to the abilities.
This is not the correct way to do it anymore,
the abilities are now different.
We now have "user_role" in the doc response
which is the correct way to get the user role
for the current document.
## Purpose
So that users have more options to choose from
## Proposal
Add mosa.cloud docs instance url
Please ensure the following items are checked before submitting your
pull request:
- [x] I have read and followed the [contributing
guidelines](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md)
- [x] I have read and agreed to the [Code of
Conduct](https://github.com/suitenumerique/docs/blob/main/CODE_OF_CONDUCT.md)
- [x] I have signed off my commits with `git commit --signoff` (DCO
compliance)
- [x] I have signed my commits with my SSH or GPG key (`git commit -S`)
- [x] My commit messages follow the required format: `<gitmoji>(type)
title description`
- [ ] I have added a changelog entry under `## [Unreleased]` section (if
noticeable change)
- [ ] I have added corresponding tests for new features or bug fixes (if
applicable)
Signed-off-by: virgile-deville <virgile.deville@beta.gouv.fr>
The expected type for the settings DOCUMENT_IMAGE_MAX_SIZE is an
integer. By not using django configurations IntegerValue, the value is
used as it and most of the time will be a string. We must use the
IntegerValue in order to cast the value in string.
On some environments keycloak returns a 'HTTPS required' message on login.
The same issue was fixed in drive by changing the 'sslRequired' value
from 'external' to 'none'.
Also upgrade keycloak up to 26.3.2
Signed-off-by: Fabre Florian <ffabre@hybird.org>
In a recent fix we had to remove the categories
from the EmojiPicker component due to a bug in the
underlying library. This commit reintroduces the
categories feature, placing them at the top of the
picker for improved user experience. The
categories help users quickly find emojis
by grouping them into relevant sections.
We set the default color as well to ensure
consistency across the emoji picker.
The drop cursor for multi column was causing
issues with the editor's usability.
This commit removes the custom drop cursor
implementation to enhance user experience.
254 characters should be sufficient for most
of our usecases.
Limit input search to 254 characters to prevent
errors caused by overly long email addresses.
When we create a new user in the demo environment,
the email address will now follow the format
user.test@example.com instead of user@example.com.
"user" was only 4 characters long, it created failing
tests in the e2e suite.
Only the input data min length was checked. We also have to check the
mex length because the levenshtein dos not accept more than 254
characters and the email field has a max length of 254
Recent improvement changes the modal title with
a h1 tag, h1 tag adds margin by default.
We remove the margin from the h1 tag to stick to
the design system.
We upgraded ESLint to version 9 in the i18n package,
which includes several improvements and fixes.
This change also involves updating the ESLint
configuration files to the new format and ensuring
compatibility with the latest ESLint features.
We upgraded ESLint to version 9 in the y-provider server,
which includes several improvements and fixes.
This change also involves updating the ESLint
configuration files to the new format and ensuring
compatibility with the latest ESLint features.
We upgraded ESLint to version 9 in the e2e app,
which includes several improvements and fixes.
This change also involves updating the ESLint
configuration files to the new format and ensuring
compatibility with the latest ESLint features.
We upgraded ESLint to version 9 in the Docs app,
which includes several improvements and fixes.
This change also involves updating the ESLint
configuration files to the new format and ensuring
compatibility with the latest ESLint features.
This allows API users to process document content, enabling the
use of Docs as a headless CMS for instance, or any kind of document
processing. Fixes#1206.
We want to configure the throttle on all doc's viewsets. In order to
monitor them, we use the MonitoredScopedRateThrottle class and a custom
callback caputing the message in sentry at the warning level.
Replace custom Docker Hub authentication with standard, secure,
official GitHub actions for improved security and maintainability.
Uses officially supported actions that follow security best practices
and receive regular updates from GitHub.
Avoid unsecure handling of GitHub secrets.
Thanks to @lebaudantoine
Added:
- 👷(CI) add bundle size check job
- ✨(frontend) use title first emoji as doc icon in tree
Changed:
- ♻️(docs-app) Switch from Jest tests to Vitest
- ♿(frontend) improve accessibility:
- 🌐(frontend) set html lang attribute dynamically
- ♿(frontend) inject language attribute to pdf export
- ♿(frontend) improve accessibility of search modal
- ♿(frontend) add correct attributes to decorative and interactive icons
- 🎨(frontend) improve nav structure
- ♿️(frontend) keyboard interaction with menu
- ♿(frontend) improve header accessibility
- ♿(frontend) improve accessibility for decorative images in editor
- ♻️(backend) fallback to email identifier when no name
- 🐛(backend) allow ASCII characters in user sub field
- ⚡️(frontend) improve fallback width calculation
Fixed:
- 🐛(makefile) Windows compatibility fix for Docker volume mounting
- 🐛(minio) fix user permission error with Minio and Windows
- 🐛(frontend) fix export when quote block and inline code
- 🐛(frontend) fix base64 font
- 🐛(backend) allow editor to delete subpages
- 🐛(frontend) fix dnd conflict with tree and Blocknote
- 🐛(frontend) fix display bug on homepage
By default a document is "restricted", a restricted
document cannot have a role "editor" or "reader".
With inheritance, a child document could have a computed
link reach different than "restricted" though.
We pass the computed link reach when we update the
link role, to be sure if follows the parent computed
link reach.
After translating to french, a selector was not
accessible anymore because the aria label
was in english. We update the selector to use the
french aria label.
We increase as well the timeout of another test
that was flaky.
Sometimes we do not have the width of some
columns in a table. In such cases, we need to
calculate a fallback width to ensure the table
is rendered correctly.
We were previously using 120 points as the
fallback width, but this has been improved
to better fit the content.
We now check the size left and distribute it
among the unknown columns.
Recent upgrade of ui-kit removed the z-index for
the modal backdrop, causing it to be hidden behind
other elements. This commit restores the z-index
to ensure the modal backdrop is displayed correctly.
We have different DND system in the page, one on the
menu tree and one in the Blocknote editor.
The menu tree was adding a transparent layer
when user were dragging element on the Blocknote
editor, blocking the Blocknote DND.
We update the ui-kit to add the prop dndRootElement,
dndRootElement is now used to specify the root element
for DND, this transparent layer is now only applied
when a drag is made from the menu tree.
It stabilize as well the drop position, making it easier to drop element.
When we were dragging an item in the doc tree,
the background color was opaque, making it difficult
to see the underlying content. The cause was
that we were overriding the transparent background
color.
## Purpose
Adds a new Docs instance, as suggested here:
https://github.com/suitenumerique/docs/discussions/1316
## External contributions
Thank you for your contribution! 🎉
Please ensure the following items are checked before submitting your
pull request:
- [x] I have read and followed the [contributing
guidelines](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md)
- [x] I have read and agreed to the [Code of
Conduct](https://github.com/suitenumerique/docs/blob/main/CODE_OF_CONDUCT.md)
- [x] I have signed off my commits with `git commit --signoff` (DCO
compliance)
- [x] I have signed my commits with my SSH or GPG key (`git commit -S`)
- [x] My commit messages follow the required format: `<gitmoji>(type)
title description`
- [ ] I have added a changelog entry under `## [Unreleased]` section (if
noticeable change)
- [ ] I have added corresponding tests for new features or bug fixes (if
applicable)
Signed-off-by: Henry-Hiles <henry@henryhiles.com>
An editor who created a subpages should be allowed to delete it.
We change the abilities to be coherent between the creation and the
deletion.
Fixes#1193
Marianne font was in base64 in the ui-kit,
it was not an optimize way to do it.
We do not have a CDN yet so the best
is to put them back in the project in
waiting for a CDN options.
git-lint steps are independant and we would like to have all checks at
once. Using the `if: always()` instruction should ensure all steps
should be run event if the previous fails.
When exporting documents, if a inline code was inside
a quote block, the PDF export was failing because the
inline code was searching the GeistMono font in
italics, which was not available.
We switch to the core "Courier" font for code marks,
which is available in italics.
We don't need to run the bundle-size-check job if
the app didn't change.
If the yarn.lock file or the app have changed, the
bundle-size-check job will be triggered.
In the UserlightSerializer, if the user has no short_name or full_name,
we have no info about the user. We decided to use the email identifier
and slugify it to have a little bit information.
On the cors_proxy endpoint, if the fetched url fails we were returning
an error 500. Instead, we log the exception and return a 400 to not
give back information to the frontend application.
The url used by the cors_proxy was not validated, other value than a
http url can be used. We use the built in URLValidator to validate it is
a valid url.
The setup-python action is able to cache the dependencies and reuse this
cache while the pyproject file has not changed. It is easy to setup,
just the package manager used has to be declared in the cache settings.
We have migrated the testing framework from Jest
to Vitest for the Docs application.
This change includes updates to test files,
configuration files, and the addition of new setup
files for Vitest.
Job that will give a report on the bundle size
of the frontend application.
Good to know if the bundle size is increasing or
decreasing and if the changes are acceptable.
Add nicely formatted messages to the Makefile to
indicate the start and end of the bootstrap process.
This will help users understand when the bootstrap
process begins and ends, improving the
overall user experience.
## Purpose
To showcase the work of the community to make docs deployment easier
## Proposal
- [x] Added README.md in /docs/installation with methods contributed by
the community
- [x] Added a list of public instances on the main README.md
- [x] Updated the warnings around Blocknote XL packages from AGPL to GPL
Please ensure the following items are checked before submitting your
pull request:
- [x] I have read and followed the [contributing
guidelines](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md)
- [x] I have read and agreed to the [Code of
Conduct](https://github.com/suitenumerique/docs/blob/main/CODE_OF_CONDUCT.md)
- [x] I have signed off my commits with `git commit --signoff` (DCO
compliance)
- [x] I have signed my commits with my SSH or GPG key (`git commit -S`)
- [x] My commit messages follow the required format: `<gitmoji>(type)
title description`
- [ ] I have added a changelog entry under `## [Unreleased]` section (if
noticeable change)
- [ ] I have added corresponding tests for new features or bug fixes (if
applicable)
---------
Signed-off-by: virgile-dev <virgile.deville@beta.gouv.fr>
With Minio Docker and Windows, the user ID needs
to be set to `0:0` to avoid permission issues.
This change ensures that the Minio container
runs with root privileges on Windows, which
is necessary for proper file access and management.
On Windows systems, Docker volume paths starting
with a single / can be interpreted incorrectly
by the Docker daemon. The double slash (//) helps
Docker on Windows properly interpret the path as
an absolute path within the container, ensuring
that the working directory is correctly set
when running mail-related yarn commands.
Improve overall accessibility of the left panel:
- ⚡️(frontend) make LeftPanelTargetFilter accessible and use Box as nav
- ⚡️(frontend) improve accessibility in left panel components
- ✅(e2e) fix e2e test to expect aria-current instead of aria-selected
- ✨(frontend) add semantic ul/li to LeftPanel
- ✨(frontend) improve favorite item a11y and update e2e test accordingly
We add some flaky tests because the aria label
selectors were not everytime in english language.
It was because the language switch was not mocked
in the e2e tests, impacting the consistency of
other concurrent tests.
We mock the language switch in the e2e tests
to ensure that the other tests are not impacted
by the language switch.
The value in the production environment .env example was missing a
trailing slash in the path. This commit adjusts this to be in the same
format as in other places.
added language="fr-FR" to <Document /> in ModalExport.tsx via cloneElement()
to improve accessibility and ensure correct screen reader pronunciation
Signed-off-by: Cyril <c.gromoff@gmail.com>
Added:
- ✨(helm) Service Account support for K8s Resources in Helm Charts
- ✨(backend) allow masking documents from the list view
- ✨(frontend) subdocs can manage link reach
- ✨(frontend) add duplicate action to doc tree
- ✨(frontend) Interlinking doc
- ✨(frontend) add multi columns support for editor
Changed:
- ♻️(frontend) search on all docs if no children
- ♻️(frontend) redirect to doc after duplicate
- 🔧(project) change env.d system by using local files
- ⚡️(frontend) improve tree stability
- ⚡️(frontend) improve accessibility
- 🛂(frontend) block drag n drop when not desktop
Fixed:
- 🐛(service-worker) Fix useOffline Maximum update depth exceeded
- 🐛(frontend) fix empty left panel after deleting root doc
- 🐛(helm) charts generate invalid YAML for collaboration API / WS
- 🐛(frontend) 401 redirection overridden
- 🐛(frontend) include root parent in search
We created the editor shortcuts hook to handle
the shortcuts for the editor.
We implemented the following shortcuts:
- "@" to open the interlinking inline content
Move some components and assets to `doc-management`
to reduce coupling between features:
- SimpleDocItem from `doc-grid` to `doc-management`
- useCreateChildDoc from `doc-tree` to `doc-management`
- isOwnerOrAdmin from `doc-tree` to `doc-management`
Scrolling on mobile devices was causing issues
with drag and drop functionality, documents were
being moved unintentionally.
This commit disables drag and drop on mobile devices
to prevent this issue.
Add support for specifying custom service accounts
in all Kubernetes resources in our Helm charts
to enable workload identity federation with managed
cloud services (PostgreSQL, Redis, etc.).
This allows deployments to authenticate to cloud
resources without embedding credentials in secrets.
When we were deleting a root document, the left panel
was getting empty. It was because the panel thought that
it was a child document and was trying clear
dynamically the panel.
Now, we are checking if the document is a root or not,
if it is a root we just redirect to the homepage.
Using the treeContext was causing issues with
the current parent detection, in many places
the context is not available.
"depth" property is more reliable than
"nb_accesses_ancestors".
To capture a 401 we were using "onError" in the
queryClient default mutation options. The problem
is this way does not capture globally the onError,
if a mutation uses as well is own "onError", it will
override the default one, causing the 401 to
not be captured anymore.
We now use MutationCache, which allows us to
capture globally the onError, even if a mutation
has its own "onError" defined, this global one will
still be called.
Once users have visited a document to which they have access,
they can't remove it from their list view anymore. Several
users reported that this is annoying because a document that
gets a lot of updates keeps popping up at the top of their list
view.
They want to be able to mask the document in a click. We propose
to add a "masked documents" section in the left side bar where the
masked documents can still be found.
Improve tree stability by limiting the requests,
we now only load the tree request one time then
we let the treeContext handle the state without
mutating it directly.
We do not do the doc subpage request anymore,
the treeContext has already the data we need,
we just need to update the tree node when needed.
- Recent upgrade highlighted a lint warning about
an unnecessary assertion in the BlockNoteToolbar component.
This commit removes the assertion to resolve the warning.
- Fix a test - upgrade causes an error on a selector click
At the bottom of the tree panel, the subdocs
were not clickable due to a CSS issue.
This commit adjusts the CSS to ensure that
the subdocs can be unfolded properly.
Sentry was reporting a "Maximum update depth exceeded" error
comming from the `useOffline` hook. We updated the hook to
avoid mutation. Seems to impact mainly edge browsers.
We had lot of problems with the previous env.d system.
Users were often confused by the need to change
the env.d files manually, leading to issues
when using the project locally.
This commit introduces a new system that uses
.env.local files, which are automatically created
and can be modified by users without affecting
the original env.d files. This should simplify
the development process and reduce confusion by
removing the need to manually edit env.d files.
Closes#890
Remove the service blocks outside the conditionals in the collaboration
API and WS templates.
Signed-off-by: Richard Jones <rich@linuxplicable.org>
The AI answer was activating the code block feature
in the editor, which was not desired.
The prompt for AI actions has been updated to
instruct the AI to return content directly
without wrapping it in code blocks or markdown
delimiters.
Using the `apk` commands with the `--no-cache` parameter for package
installation and upgrade will prevent the package index from being
cached and reduce the built image size.
## Purpose
Update the issue template to help contributors
Please ensure the following items are checked before submitting your
pull request:
- [x] I have read and followed the [contributing
guidelines](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md)
- [x] I have read and agreed to the [Code of
Conduct](https://github.com/suitenumerique/docs/blob/main/CODE_OF_CONDUCT.md)
- [x] I have signed off my commits with `git commit --signoff` (DCO
compliance)
- [x] I have signed my commits with my SSH or GPG key (`git commit -S`)
- [x] My commit messages follow the required format: `<gitmoji>(type)
title description`
- [ ] I have added a changelog entry under `## [Unreleased]` section (if
noticeable change)
- [ ] I have added corresponding tests for new features or bug fixes (if
applicable)
---------
Signed-off-by: virgile-dev <virgile.deville@beta.gouv.fr>
Fixed:
- 🌐(frontend) keep simple tag during export
- 🐛(back) manage can-edit endpoint without created room in the ws
- 🐛(frontend) fix action buttons not clickable
- 🐛(frontend) fix crash share modal on grid options
If the title was too long, or the children deepness too deep, the action
buttons in the doc tree were not clickable.
This commit fixes the issue by ensuring that the action buttons are
always clickable, regardless of the title length or children depth.
In a scenario where the first user is editing a docs without websocket
and nobody has reached the websocket server first, the y-provider
service will return a 404 and we don't handle this case in the can-edit
endpoint leading to a server error.
Added:
- ✨(frontend) multi-pages
- ✨(frontend) Duplicate a doc
- ✨Ask for access
- ✨(frontend) add customization for translations
- ✨(backend) add ancestors links definitions to document abilities
- ✨(backend) include ancestors accesses on document accesses list view
- ✨(backend) add ancestors links reach and role to document API
- 📝(project) add troubleshoot doc
- 📝(project) add system-requirement doc
- 🔧(front) configure x-frame-options to DENY in nginx conf
- ✨(backend) allow to disable checking unsafe mimetype on attachment upload
- ✨(doc) add documentation to install with compose
- ✨ Give priority to users connected to collaboration server
(aka no websocket feature)
Changed:
- ♻️(backend) stop requiring owner for non-root documents
- ♻️(backend) simplify roles by ranking them and return only the max role
- 📌(yjs) stop pinning node to minor version on yjs docker image
- 🧑💻(docker) add .next to .dockerignore
- 🧑💻(docker) handle frontend development images with docker compose
- 🧑💻(docker) add y-provider config to development environment
- ⚡️(frontend) optimize document fetch error handling
Fixed:
- 🐛(backend) fix link definition select options linked to ancestors
- 🐛(frontend) table of content disappearing
- 🐛(frontend) fix multiple EmojiPicker
- 🐛(frontend) fix meta title
- 🔧(git) set LF line endings for all text files
- 📝(docs) minor fixes to docs/env.md
- ✨support `_FILE` environment variables for secrets
Removed:
- 🔥(frontend) remove Beta from logo
Children does not have accesses created for now, they inherit from their
parent for now. We have to ignore access creation while owrk on the
children accesses has not been made.
After duplicating a document, the tree is now
refreshed to reflect the new structure.
This ensures that the user sees the updated
document tree immediately after the duplication
action.
Importing the french translation broke a test
because the subject was not in english anymore.
We change the admin user language to english
to keep the subject in english.
We change the icon for the duplicate feature
in the document toolbox and the documents grid
actions from 'call_split' to 'content_copy'
to better reflect the action of duplicating a
document.
The blocking edition modal could be flickring, because
the connection to the collaborative server can take
a bit of time.
We set a timeout to ensure the loading state
is cleared after a reasonable time.
In a first version we want to restrict the ask for access feature only
to root document. We will work on opening to all documents when iherited
permissions will be implemented.
- Removed 'feature/doc-dnd' branch from the Docker Hub workflow to
streamline deployment processes.
- Updated document creation tests to replace 'New page' button
references with 'New doc' for consistency.
- Enhanced test cases to improve clarity and ensure accurate
verification of document functionalities.
- Added new utility function for creating root subpages, improving test
maintainability.
- Introduced a new `AlertModal` component for confirmation dialogs.
- Updated `DocToolBoxLicenceAGPL` and `DocToolBoxLicenceMIT` to include
`isRootDoc` prop for better document management.
- Enhanced `DocShareModal` to conditionally render content based on the
root document status.
- Improved `DocInheritedShareContent` to display inherited access
information more effectively.
- Refactored `DocRoleDropdown` to handle access removal actions and
improve role management.
- Updated `DocShareMemberItem` to accommodate new access management
features.
- Added a horizontal separator to the dropdown menu for better visual
distinction between options.
- Updated padding in the quick search input for improved layout
consistency.
- Adjusted margin in the quick search group for better spacing.
- Increased vertical padding in quick search item content for enhanced
readability.
- Modified the horizontal separator to accept custom padding for more
flexible styling.
- Improved left panel styling to manage overflow behavior effectively.
- Removed unused skeleton loading styles from globals.css to clean up
the codebase.
During the multipage dev, the code base has changed a lot and rebase
after rebase it has come difficult to manage fixup commits. This commits
fix modification made that can be fixup in previous commits. The
persmission AccessPermission has been renamed in
ResourceWithAccessPermission and should be used in the
DocumentAskForAccessViewSet. A migration with the same dependency
exists, the last one is fixed. And a test didn't have removed an
abilitites.
- update tests description
- Corrected minor typos in test descriptions to enhance readability.
- Ensured that all test cases clearly convey their purpose and expected
outcomes.
- Introduced new utility functions for managing document sharing,
including `searchUserToInviteToDoc`, `addMemberToDoc`, and
`updateShareLink`.
- Updated existing tests to verify inherited share access and link
visibility features.
- Refactored document access handling in tests to improve clarity and
maintainability.
- Added comprehensive tests for inherited share functionalities,
ensuring proper role and access management for subpages.
- Added a new component `DocInheritedShareContent` to display inherited
access information for documents.
- Updated `DocShareModal` to include inherited share content when
applicable.
- Refactored `DocRoleDropdown` to improve role selection messaging based
on inherited roles.
- Enhanced `DocVisibility` to manage link reach and role updates more
effectively, including handling desynchronization scenarios.
- Improved `DocShareMemberItem` to accommodate inherited access logic
and ensure proper role management.
- Simplified the `getDocAccesses` function by removing pagination
parameters.
- Updated the `useDocAccesses` hook to reflect changes in the API
response type.
- Removed the `useDocAccessesInfinite` function to streamline document
access management.
- Updated the `Access` and `Doc` interfaces to include new properties
for role management and document link reach.
- Introduced utility functions to handle document link reach and role,
improving the logic for determining access levels.
- Refactored the `isOwnerOrAdmin` function to simplify role checks for
document ownership and admin status.
- Created new files for managing subdocuments and detaching documents.
- Refactored API request configuration to use an improved configuration
type.
- Removed unnecessary logs from the ModalConfirmDownloadUnsafe
component.
New components were created to manage subpages in the document tree,
including the ability to add, reorder, and view subpages. Tests were
added to verify the functionality of these features. Additionally, API
changes were made to manage the creation and retrieval of document
children.
Added a new feature for moving documents within the user interface via
drag-and-drop. This includes the creation of Draggable and Droppable
components, as well as tests to verify document creation and movement
behavior. Changes have also been made to document types to include user
roles and child management capabilities.
Added several new dependencies to the `package.json` file, including
`@dnd-kit/core`, `@dnd-kit/modifiers`, `@fontsource/material-icons`, and
`@gouvfr-lasuite/ui-kit`.
With the soft delete feature, relying on the is_leaf method from the
treebeard is not accurate anymore. To determine if a node is a leaf, it
checks if the number of numchild is equal to 0. But a node can have soft
deleted children, then numchild is equal to 0, but it is not a leaf
because if we want to add a child we have to look for the last child to
compute a correct path. Otherwise we will have an error saying that the
path already exists.
We were returning the list of roles a user has on a document (direct
and inherited). Now that we introduced priority on roles, we are able
to determine what is the max role and return only this one.
This commit also changes the role that is returned for the restricted
reach: we now return None because the role is not relevant in this
case.
We were returning too many select options for the restricted link reach:
- when the "restricted" reach is an option (key present in the returned
dictionary), the possible values for link roles are now always None to
make it clearer that they don't matter and no select box should be
shown for roles.
- Never propose "restricted" as option for link reach when the ancestors
already offer a public access. Indeed, restricted/editor was shown when
the ancestors had public/read access. The logic was to propose editor
role on more restricted reaches... but this does not make sense for
restricted since the role does is not taken into account for this reach.
Roles are set by each access line assign to users/teams.
The frontend needs to know what to display on an access. The maximum
role between the access role and the role equivalent to all accesses
on the document's ancestors should be computed on the backend.
We reduce the number of options even more by treating link reach
and link role independently: link reach must be higher than its
ancestors' equivalent link reach and link role must be higher than
its ancestors' link role.
This reduces the number of possibilities but we decided to start
with the most restrictive and simple offer and extend it if we
realize it faces too many criticism instead of risking to offer
too many options that are too complex and must be reduced afterwards.
The frontend requires this information about the ancestor document
to which each access is related. We make sure it does not generate
more db queries and does not fetch useless and heavy fields from
the document like "excerpt".
There is a delay between the time the signature is issued and the
time it is checked. Although this delay is minimal, if the signature
is issued at the end of a second, both timestamps can differ of 1s.
> assert response["X-Amz-Date"] == timezone.now().strftime("%Y%m%dT%H%M%SZ")
AssertionError: assert equals failed '20250504T175307Z' '20250504T175308Z'
If root documents are guaranteed to have a owner, non-root documents
will automatically have them as owner by inheritance. We should not
require non-root documents to have their own direct owner because
this will make it difficult to manage access rights when we move
documents around or when we want to remove access rights for someone
on a document subtree... There should be as few overrides as possible.
This field is set only on the list view when all accesses for a given
document and all its ancestors are listed. It gives the highest role
among all accesses related to each document.
The latest refactoring in a445278 kept some factorizations that are
not legit anymore after the refactoring.
It is also cleaner to not make serializer choice in the list view if
the reason for this choice is related to something else b/c other
views would then use the wrong serializer and that would be a
security leak.
This commit also fixes a bug in the access rights inheritance: if a
user is allowed to see accesses on a document, he should see all
acesses related to ancestors, even the ancestors that he can not
read. This is because the access that was granted on all ancestors
also apply on the current document... so it must be displayed.
Lastly, we optimize database queries because the number of accesses
we fetch is going up with multi-pages and we were generating a lot
of useless queries.
On a document, we need to display the status of the link (reach and
role) taking into account the ancestors link reach/role as well as
the current document.
We were returning the list of roles a user has on a document (direct
and inherited). Now that we introduced priority on roles, we are able
to determine what is the max role and return only this one.
This commit also changes the role that is returned for the restricted
reach: we now return None because the role is not relevant in this
case.
This will allow us to simplify the get_abilities method. It is also
more efficient because we have computed this definitions dict and
the the get_select_options method was doing the conversion again.
We are going to need to compare choices to materialize the fact that
choices are ordered. For example an admin role is higer than an
editor role but lower than an owner role.
We will need this to compute the reach and role resulting from all
the document accesses (resp. link accesses) assigned on a document's
ancestors.
The document accesses a user have on a document's ancestors also apply
to this document. The frontend needs to list them as "inherited" so we
need to add them to the list.
Adding a "document_id" field on the output will allow the frontend to
differentiate between inherited and direct accesses on a document.
The document viewset was overriding the get_queryset method from its
own mixin. This was a sign that the mixin was not optimal anymore.
In the next commit I will need to complexify it further so it's time
to refactor the mixin.
If anonymous users have reader access on a parent, we were considering
that an edge use case was interesting: allowing an authenticated user
to still be editor on the child.
Although this use case could be interesting, we consider, as a first
approach, that the value it carries is not big enough to justify the
complexity for the user to understand this complex access right heritage.
We were returning too many select options for the restricted link reach:
- when the "restricted" reach is an option (key present in the returned
dictionary), the possible values for link roles are now always None to
make it clearer that they don't matter and no select box should be
shown for roles.
- Never propose "restricted" as option for link reach when the ancestors
already offer a public access. Indeed, restricted/editor was shown when
the ancestors had public/read access. The logic was to propose editor
role on more restricted reaches... but this does not make sense for
restricted since the role does is not taken into account for this reach.
Roles are set by each access line assign to users/teams.
We added a system to know if a user is alone
on a document or not. We adapt the
frontend to block the edition only
when the user is not alone on the document.
An already existing feature flag
COLLABORATION_WS_NOT_CONNECTED_READY_ONLY was used bu the frontend
application to disable or not the edition for a user not connected to
the websocket. We want to reuse it in the backend application to disable
or not the no websocket feature.
The endpoint can_edit is added to the DocumentViewset, it will give the
information to the frontend application id the current user can edit the
Docs based on the no-websocket rules.
When a document is updated, users not connected to the collaboration
server can override work made by other people connected to the
collaboration server. To avoid this, the priority is given to user
connected to the collaboration server. If the websocket property in the
request payload is missing or set to False, the backend fetch the
collaboration server to now if the user can save or not. If users are
already connected, the user can't save. Also, only one user without
websocket can save a connect, the first user saving acquire a lock and
all other users can't save.
To implement this behavior, we need to track all users, connected and
not, so a session is created for every user in the
ForceSessionMiddleware.
We need a new endpoint in the y-provider server allowing the backend to
retrieve the number of active connections on a document and if a session
key exists.
Handle the raw payloads in requests and responses to convert-endpoint.
This change replaces Base64-encoded I/O with direct binary streaming,
yielding several benefits:
- **Network efficiency**: Eliminates the ~33% size inflation of Base64,
cutting bandwidth and latency.
- **Memory savings**: Enables piping DOCX (already compressed) buffers
straight to DocSpec API without holding, encoding and decoding multi-MB
payload in RAM.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
Accept raw payload on convert-endpoint and respond with raw Yjs payload
This change replaces Base64-encoded I/O with direct binary streaming,
yielding several benefits:
- **Network efficiency**: Eliminates the ~33% size inflation of Base64,
cutting bandwidth and latency.
- **Memory savings**: Enables piping DOCX (already compressed) buffers
straight to DocSpec API without holding, encoding and decoding multi-MB
payload in RAM.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
Return 401 Unauthorized for missing/invalid API keys (per RFC 7235);
403 is reserved for valid-but-forbidden credentials.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
Migrated from jest to vitest for server/y-provider, gaining faster runs,
esm-native support and cleaner mocking.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
Renamed the `convert_markdown` method to `convert` to prepare for an
all-purpose conversion endpoint, enabling support for multiple formats
and simplifying future extension.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
The duplicate was also able for anonynous user if they can read it. We
have to restrict it to at least reader authenticated otherwise no access
will be created on the duplicated document.
We were maintaining two separate components
for AGPL and MIT license exports.
This commit consolidates the functionality into
a single component that handles both licenses,
simplifying the codebase and reducing duplication.
Renamed the `convert-markdown` endpoint to `convert` as a
general-purpose conversion endpoint for integration with DocSpec
conversion (DOCX import), without altering its existing functionality.
In a future contribution, this endpoint will not only support conversion
from Markdown -> BlockNote -> Yjs but also directly BlockNote -> Yjs.
Signed-off-by: Stephan Meijer <me@stephanmeijer.com>
We want to configure cronjobs. Instead of declaring them one by one, we
use a CronJobList, the will all have the same pattern, mostly the
command and the schedule will change.
Allow configuration variables that handles secrets, like
`DJANGO_SECRET_KEY` to be able to read from a file which is given
through an environment file.
For example, if `DJANGO_SECRET_KEY_FILE` is set to
`/var/lib/docs/django-secret-key`, the value of `DJANGO_SECRET_KEY` will
be the content of `/var/lib/docs/django-secret-key`.
Improve separation of concerns in the DocShareModal
component.
The member and invitation list are now
in a separate component.
It will help us to integrate cleanly the
request access list.
Add the action accepting a request to access a document. It is possible
to override the role from the request and also update an existing
DocumentAccess
We introduce a new model for user wanted to access a document or upgrade
their role if they already have access.
The viewsets does not implement PUT and PATCH, we don't need it for now.
We want to protect all requests from django with content security
policy header. We use the djang-csp library and configure it with
default values.
Fixes#1000
The db engine postgresql_psycopg2 does not exists anymore in django but
for BC compat it is possible to use it in the configuration and it is
replace by postgresql at runtime. We changed this settings to use the
good one.
We added the possibility to scan all uploaded files with an anti malware
solution. Depending the backend used, we want to give the possibility to
check the file mimtype to determine if this one is tagged as unsafe or
not. To this you can set the environment variable
DOCUMENT_ATTACHMENT_CHECK_UNSAFE_MIME_TYPES_ENABLED to False. The
default value is True.
Flakiness in e2e tests has been reduced by:
- Adding waits for media-check processing in image tests.
- Ensuring that slash menu resets are handled
correctly to avoid flakiness.
- Wait for the Download button to be stable before clicking
We have the e2e test "it creates a doc server way"
that is quite complicated to run locally, because
it requires the `DJANGO_SERVER_TO_SERVER_API_TOKENS`
environment variable to be set in "env.d/development/common".
We moved `DJANGO_SERVER_TO_SERVER_API_TOKENS` from
"env.d/development/common.e2e.dist" to
"env.d/development/common.dist", by doing so,
this variable will be set by default in the
"env.d/development/common" file, the test will now run
without any additional configuration.
We upgraded to jest 30.0.3.
This upgrade updated jsdom and jsdom now do not
allows to mock window.location.
See: https://github.com/jsdom/jsdom/issues/3492
This commit fixes this issue.
## Purpose
Make self hosting of Docs easier with an example of a deployment
procedure with docker compose and document how to configure Docs.
While https://github.com/suitenumerique/docs/pull/583 propose an easy
way to deploy Docs with docker and Make, here we describe more in
details the various steps and requirements to deploy Docs.
## Proposal
- [x] example to deploy and configure keycloak
- [x] example to deploy and configure minio
- [x] example to configure proxy and certs
- [x] example to deploy and configure Docs
## Improvements
- [x] Rephrase description of environment variables and categorize
- [x] Use template for nginx conf
Fixes https://github.com/suitenumerique/docs/issues/561
Supersedes https://github.com/suitenumerique/docs/pull/583
A one liner quick start could be a nice addition:
- [ ] merge all services in a single compose
- [ ] scripts to generate secrets
Signed-off-by: unteem <timothee@indie.host>
In local development the notification to
the yprovider server was not working anymore
because of a recent change in the container name.
We adapt the env variables to match the new
container name.
Reduce unnecessary fetch requests when retrieving documents with permission
or authentication issues. Previous implementation was triggering multiple
document requests despite having sufficient error information from initial
attempt to determine appropriate user redirection.
Additionally, fix issue where resetting the auth cache was triggering redundant
authentication verification requests. The responsibility for checking auth
status should belong to the 401 page component on mount, rather than being
triggered by cache resets during error handling.
Known limitations:
- Not waiting for async function completion makes code harder to
maintain
- Added loading spinner as temporary solution to prevent UI flicker
- Future improvement should implement consistent error-based redirects rather
than rendering error messages directly on document page
Stop retry attempts when receiving 401 Unauthorized from /me endpoint since
this clearly indicates authentication status. The original purpose of the /me
call is simply to determine if user is authenticated, and a 401 provides
sufficient information.
Prevents unnecessary network requests caused by React Query's automatic retry
behavior when re-raising exceptions, which was hiding the 401 status. Improves
performance and reduces server load during authentication failures.
Remove the `auth-url` annotation and add the
`COLLABORATION_BACKEND_BASE_URL` variable, introduced in 3.0.0.
Mount the development CA to the yProvider container to allow
TLS connections with the backend.
Fix the mount path for development CA in the backend container.
Signed-off-by: eduxstad <eduxstad@gmail.com>
The API has the response header x-frame-options configure to DENY and
nothing is configure in the nginx configuring managing the frontend
application. We want to have the same value. The header is added on all
locations.
Django 5.2 is now mature enough and we can use it in production.
In some tests the number of sql queries is increasing. This is because
the `full_clean` method called in the `save` method on all our models is
creating a transaction, so a savepoint and release is added.
We also fix deprecated warning in this commit.
Our Helm chart wasn't suitable for use with Helm alone because jobs
remained after deployment. We chose to configure ttlSecondsAfterFinished
to clean up jobs after a period of time.
In order to speed the rebuild of images, the --no-cache option is
removed by default. If we want to build the images without cache, the
cache paramter must be used.
We want to run the e2e tests using the frontend and y-provider
production images. We created a dedicated compose file adding just
missing services. These services are built in the CI.
To have a better developer experience, the y-provider service run in dev
mode, allowing hot reload when a file is modified. To avoid issue with
shared node_modules, they are mounted in a separated volume to not have
then in the local directory.
We want a serice in compose starting the frontend application in
development mode. We want to take the advantage of the hot reload
module, so the sources are mounted inside the container.
Windows users are by default using CRLF line endings,
which can cause issues with some tools and
environments. This commit sets the `.gitattributes`
file to enforce LF line endings for all text
files in the repository.
The settings CORS_ALLOW_ALL_ORIGINS was set to True by default.
This error is inherited from a old mistake made back in the days while
working on the initial impress demo.
This is not something we want, this should be only allowed in
development. We change the value in all the manifests in order to have
the desired behavior in non development environments.
The meta title was flickering, it was adding the
doc title, then it was coming back to the default
title.
This was due to the way the next Head component
render data.
We now use a more stable way to set the title.
emoji-mart is used to display emojis in the editor.
It is used by the callout block and by
Blocknotes editor. The problem is that the emoji-mart
is a singleton, so if Blocknotes components init
the emoji-mart first, the picker in the callout block
will not display correctly.
This commit fixes the issue by initializing
the emoji-mart in the callout block first.
We node service in doecker compose can be a helper to use node locally
without installing it. Docs requires at least node 22 so we upgrade it
to node 22.
- Language will only be changed if different from current language
- Added test for custom translations
Signed-off-by: Robin Weber <weber@b1-systems.de>
- Refactors "useTranslationsCustomizer" to "useCustomTranslations"
- Refactors "useLanguageSynchronizer" to "useSynchronizedLanguage"
- Refactors "LanguagePicker" to better reflect its component role
- Refactors "LanguagePicker" to use "useSynchronizedLangue"
- Removes unused "useChangeUserLanguage"
- To change the user language, use "useAuthMutation" instead
Signed-off-by: Robin Weber <weber@b1-systems.de>
Introduces dedicated mutations
(for authentication/user operations)
separating them from queries to align with best practices
for data fetching and state management.
Queries remain responsible for READ operations, while mutations
now handle CREATE, UPDATE, and DELETE actions (for user data)
improving separation of concerns.
Signed-off-by: Robin Weber <weber@b1-systems.de>
If users were not connected to the collaboration
server, they were not be able to edit documents.
We decided to add a feature flag on this feature
as it can be quite restrictive.
We can now enable or disable this feature at runtime
thanks to the env variable
"COLLABORATION_WS_NOT_CONNECTED_READY_ONLY".
The favicons were still with the dsfr color.
We added the generic favicon in the assets folder.
The favicon can be a url loaded from the theme,
so when Drive will be running, we will be able
to store the dsfr favicons there, and remove them
from the repo.
We want to desaturate the images system in the
generic theme to make them less colorful and more
in line with the overall theme.
We added a special class to the images
that need to be desaturated. Other property
then desaturated can be apply depending on the theme.
By default Docs will not be on the dsfr theme but
on the generic theme. La Gaufre is part of the dsfr
theme and is removed from the generic theme.
Same for the "beta" keyword and the "proconnect"
buttons.
Legal pages are not needed anymore in the application.
In the dsfr instances, the legal pages will be
displayed on a Docs pages.
We let the users of Docs managing the legal pages
on their own instances.
To have different footer per instance the
content of the footer is now configurable
from the theme customization file.
See THEME_CUSTOMIZATION_FILE_PATH env var.
In the malware_detection callback we are using a different logger named
docs.security. We want to configure a logger in the logging settings
handling it.
We want to have the media-check url returned on the attachment-upload
response instead of the media url directly. The front will know the
endpoint to use to check the media status.
With the usage of a malware detection system, we need a way to know the
file status. The front will use it to display a loader while the analyse
is not ended.
Problem:
- Default Express JSON parser limit (100kb) is insufficient for larger
transcription files
- 2-hour audio transcriptions slightly exceed the 100kb limit, causing request
failures
Solution:
- Implemented custom middleware to apply different JSON parser configurations
based on route
- Applied 500kb limit specifically for transcription conversion endpoints
- Maintained default limits for all other routes to preserve security
Technical notes:
- Could not find a built-in Express solution to specify parser config per route
- Custom middleware conditionally applies the appropriate parser configuration
Fix certificate directory reference that still pointed to Python 3.12 folder
after upgrading to Python 3.13. Resolves certificate verification errors in
tilt stack caused by incorrect certificate location.
When the user is offline, we allow editing the
document in the editor.
Their is not a reliable way to know if the user is
offline or online except by doing a network request
and checking if an error is thrown or not.
To do so, we created the OfflinePlugin inherited
from the WorkboxPlugin.
It will inform us if the user is offline or online.
We then dispatch the information to our application
thanks to the useOffline hook.
If an editor is working on a shared document but
is not connected to the collaborative server
we are now blocking the edition.
It is to avoid none connected users to
overwrite the document with connected
users.
Upgrade @gouvfr-lasuite/ui-kit from 0.5.0 to 0.6.0.
Some properties have been removed in 0.5.0, which
causes the design of the app to be broken.
Version 0.6.0 has as well some breaking changes,
about the "logo" properties that are not available anymore.
We fix them in this commit.
Last upgrade of Blocknote to 0.30.0 broke the SVG
export. The previewWidth can be undefined, which causes the
export to fail. This commit adds a fallback
width in case previewWidth is undefined.
The page '/login' was replaced with '/home',
but some users may still have the old URL in their
bookmarks, it can create a loop during the
authentication process.
We redirect the user to '/home' if they try to access
'/login' page, it will prevent edge cases.
Update the documentation to include the
missing environment variables.
The missing environment variables are involved
in the build process of the frontend image.
The mount path used in the backend deployment to mount the customization
file ConfigMap is not the same from the default settings. To avoid extra
configuration we change it to refrlect the default value of
settings.THEME_CUSTOMIZATION_FILE_PATH
The env.d/development/common file sets
AI_FEATURE_ENABLED=true.
When pytest starts it imports these variables, so
the /api/v1.0/config endpoint returns
AI_FEATURE_ENABLED=True and the test_api_config
assertion fails.
Explicitly overriding AI_FEATURE_ENABLED=False in
test_api_config restores the expected behaviour
and makes the whole test-suite green.
Signed-off-by: ReinforcedKnowledge <reinforced.knowledge@gmail.com>
We want to change the cache key prefix using an environment variable.
This settings can be changed at every deployment in order to reset to
use a fresh new cache.
In order to load a custom theme file with our helm chart, we allow to
load the content of a file into a config map and then use this configmap
as a volume in the backend deployment
We want to customize the theme by using a configuration file. This
configuration file path can be defined using the settings
THEME_CUSTOMIZATION_FILE_PATH. If this file does not exists or is an
invalid json, an empty json object will be added in the config endpoint.
In the attachment_upload method, the status in the file metadata to
processing and the malware_detection backend is called. We check in the
media_auth if the status is ready in order to accept the request.
We want to use the malware_detection module from lasuite library. We add
a new setting MALWARE_DETECTION to configure the backend we want to use.
The callback is also added. It removes the file if it is not safe or
change it's status in the metadata to set it as ready.
Library we are using can have celery shared task. We have to make some
modification to load them earlier when the celery app is configure and
when the impress app is loaded.
We have some packages that are not MIT compatible,
so if the env var MIT_ONLY is set to true,
we don't build the application with features
that are not MIT compatible.
For the moment, it concerns only the export packages.
We need functionalities and data to implement a custom emoji picker
component, as blocknote's emojipicker component triggers and uses cases
are limited.
add to package.json the following packages:
- "emoji-mart": provides functions and components for
displaying, searching and selecting emojis.
- @emoji-mart-data: offers pre-configured sets of emojis.
- @emoji-mart/react: React Picker component
When we copy paste a list, the pasted
list is not formatted correctly.
By pinning prosemirror-model to 1.25.0,
we avoid this issue.
We added "prosemirror-model" to the
ignored dependencies of Renovate to
avoid to have a bump until the patch
on the Blocknote.js side.
This is false by default.
Without this env setting on true AI will not be available in the
docs application.
The setting was missing in the env options.
We cannot add new js dependency locally when we bind the
frontend with the y-provider service. It results in
"EPERM: operation not permitted" when the `node_modules`
has to be updated.
Better to remove the binding, we can add the binding
locally during development on the y-provider.
Added:
- 🚸(backend) make document search on title
accent-insensitive
- 🚩 add homepage feature flag
- ✨(settings) Allow configuring PKCE for the SSO
- 🌐(i18n) activate chinese and spanish languages
- 🔧(backend) allow overwriting the data directory
- ➕(backend) add `django-lasuite` dependency
(breaking change)
- ✨(frontend) advanced table features
Changed:
- ⚡️(frontend) reduce unblocking time for config
- ♻️(frontend) bind UI with ability access
- ♻️(frontend) use built-in Quote block
Fixed:
- 🐛(nginx) fix 404 when accessing a doc
- 🔒️(drf) disable browsable HTML API renderer
- 🔒(frontend) enhance file download security
- 🐛(backend) race condition create doc
- 🐛(frontend) fix breaklines in custom blocks
We're going to make languages configurable
per instance, but until we manage that, we're going
to remove Chinese from the default language list.
- Remove the chinese language from the default language
list.
- Change Spanish to Español
We added advanced table features to the
table editor, including:
- split / merge cells
- cell background color
- cell text color
- header
We adapted the export and brought some improvements
compare to the previous version.
The export PDF supports colspan (merge horizontally),
but does not support the rowspan (merge vertically)
for now.
To reduce the bundles size, the highlight syntax
library is not included in blocknote core anymore.
We need to add a separate dependency in order
to have the code block syntax highlight feature.
Some actions were not available in the frontend
but allowed in the backend, this commit binds the frontend
ui with the ability access coming from the backend.
The `BrowsableAPIRenderer` generates a form to test POST/PUT/... actions
and fill the FK fields with unfiltered data. This issue has been spoted
on visio and fixedsuitenumerique/meet#508
The keycloak configuration used in dev environment is too generic and we
can have a conflict with other project that are using the same ingress
domain. Also the namespace was missing in the keycloak extra ConfigMap
leading to creating it in the default namespace.
We improve the nginx way to access to a specific
doc.
We stop to wait for a initial attempt that
give a 404. If we see a UUID in the url we will
redirect to the doc/[id] page. Next will then
manage the 404.
## Purpose
Deployments that don't rely on Docker should be given the option to use
a different data directory.
## Proposal
Allow customization of the `DATA_DIR` through an environment variable of
the same name.
If the environment variable is not set the behaviour remains the same as
before.
Signed-off-by: Martin Weinelt <hexa@darmstadt.ccc.de>
## Purpose
Added a safety check for URLs in the FileDownloadButton component. Now,
before opening a URL, it verifies if the URL is safe using the isSafeUrl
function.
This prevents potentially unsafe URLs from being opened in a new tab.
All the spanish and chinese translations are complete on crowdin. We
activate it in django settings and download all translations from
crowdin
Signed-off-by: virgile-deville <virgile.deville@beta.gouv.fr>
When 2 docs are created almost at the same time,
the second one will fail because the first one.
We get a unicity error on the path key already
used ("impress_document_path_key").
To fix this issue, we will lock the table the
time to create the document, the next query will
wait for the lock to be released.
We will serve the config from the cache if available
in waiting for the config to be loaded.
It will remove the loading time for the config except
when the config is not available in the cache.
This should work in both cases:
- search for "vélo" when the document title contains "velo"
- search for "velo" when the document title contains "vélo"
2025-04-17 20:28:14 +02:00
787 changed files with 80257 additions and 27517 deletions
- Check the other [issues](https://github.com/suitenumerique/docs/issues) before filing your own
- If your report is related to the ([BlockNote](https://github.com/TypeCellOS/BlockNote)) text editor, [file it on their repo](https://github.com/TypeCellOS/BlockNote/issues). If you're not sure whether your issue is with BlockNote or Docs, file it on our repo: if we support it, we'll backport it upstream ourselves 😊, otherwise we'll ask you to do so.
**Problematic behavior**
A clear and concise description of the behavior.
@@ -18,8 +22,8 @@ A clear and concise description of what you expected to happen (or code).
3. And then the bug happens!
**Environment**
-Impress version:
-Platform:
-Docs version:
-Instance url:
**Possible Solution**
<!--- Only if you have suggestions on a fix for the bug -->
about: If you have a question 💬, or something was not clear from the docs!
labels: ["support", "triage"]
---
## Support request
**Checks before filing**
Please make sure you have read our [main Readme](https://github.com/suitenumerique/docs).
<!-- ^ Click "Preview" for a nicer view! ^
We primarily use GitHub as an issue tracker. If however you're encountering an issue not covered in the docs, we may be able to help! -->
---
Please make sure you have read our [main Readme](https://github.com/numerique-gouv/impress).
Also make sure it was not already answered in [an open or close issue](https://github.com/numerique-gouv/impress/issues).
Also make sure it was not already answered in [an open or close issue](https://github.com/suitenumerique/docs/issues?q=is%3Aissue%20state%3Aopen%20label%3Asupport).
If your question was not covered, and you feel like it should be, fire away! We'd love to improve our docs! 👌
:rocket: Preview will be available at [https://${{ github.event.pull_request.number }}-docs.ppr-docs.beta.numerique.gouv.fr/](https://${{ github.event.pull_request.number }}-docs.ppr-docs.beta.numerique.gouv.fr/)
You can use the existing account with these credentials:
- username: `docs`
- password: `docs`
You can also create a new account if you want to.
Once this Pull Request is merged, the preview will be destroyed.
@@ -42,34 +42,38 @@ Examples of unacceptable behavior include:
## Enforcement Guidelines
- Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of this
- Community leaders will follow these Community Impact Guidelines in determining the consequences for any action they deem in violation of the following Code of Conduct
## Code of Conduct:
1. Correction
### 1. Correction
Community Impact: Use of inappropriate language or other behavior deemed unprofessional or unwelcome in the community.
Consequence: A private, written warning from community leaders, providing clarity around the nature of the violation and an explanation of why the behavior was inappropriate. A public apology may be requested.
2. Warning
### 2. Warning
Community Impact: A violation through a single incident or series of actions.
Consequence: A warning with consequences for continued behavior. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period of time. This includes avoiding interactions in community spaces as well as external channels like social media. Violating these terms may lead to a temporary or permanent ban.
3. Temporary Ban
### 3. Temporary Ban
Community Impact: A serious violation of community standards, including sustained inappropriate behavior.
Consequence: A temporary ban from any sort of interaction or public communication with the community for a specified period of time. No public or private interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, is allowed during this period. Violating these terms may lead to a permanent ban.
4. Permanent Ban
### 4. Permanent Ban
Community Impact: Demonstrating a pattern of violation of community standards, including sustained inappropriate behavior, harassment of an individual, or aggression toward or disparagement of classes of individuals.
Consequence: A permanent ban from any sort of public interaction within the community.
Attribution
## Attribution
This Code of Conduct is adapted from the Contributor Covenant, version 2.1, available at https://www.contributor-covenant.org/version/2/1/code_of_conduct.html.
Community Impact Guidelines were inspired by Mozilla's code of conduct enforcement ladder.
Community Impact Guidelines were inspired by Mozilla's [code of conduct enforcement ladder](https://github.com/mozilla/inclusion/blob/master/code-of-conduct-enforcement/consequence-ladder.md).
For answers to common questions about this code of conduct, see the FAQ at https://www.contributor-covenant.org/faq. Translations are available at https://www.contributor-covenant.org/translations.
Thank you for taking the time to contribute! Please follow these guidelines to ensure a smooth and productive workflow. 🚀🚀🚀
To get started with the project, please refer to the [README.md](https://github.com/suitenumerique/docs/blob/main/README.md) for detailed instructions.
To get started with the project, please refer to the [README.md](https://github.com/suitenumerique/docs/blob/main/README.md) for detailed instructions on how to run Docs locally.
Contributors are required to sign off their commits with `git commit --sign-off`: this confirms that they have read and accepted the [Developer's Certificate of Origin 1.1](https://developercertificate.org/).
Contributors are required to sign off their commits with `git commit --signoff`: this confirms that they have read and accepted the [Developer's Certificate of Origin 1.1](https://developercertificate.org/). For security reasons we also require [signing your commits with your SSH or GPG key](https://docs.github.com/en/authentication/managing-commit-signature-verification/about-commit-signature-verification) with `git commit -S`.
Please also check out our [dev handbook](https://suitenumerique.gitbook.io/handbook) to learn our best practices.
## Help us with translations
You can help us with translations on [Crowdin](https://crowdin.com/project/lasuite-docs).
Your language is not there? Request it on our Crowdin page 😊.
Your language is not there? Request it on our Crowdin page 😊 or ping us on [Matrix](https://matrix.to/#/#docs-official:matrix.org) and let us know if you can help with translations and/or proofreading.
## Creating an Issue
@@ -35,10 +35,14 @@ All commit messages must adhere to the following format:
`<gitmoji>(type) title description`
* <**gitmoji**>: Use a gitmoji to represent the purpose of the commit. For example, ✨ for adding a new feature or 🔥 for removing something, see the list here: <https://gitmoji.dev/>.
* <**gitmoji**>: Use a gitmoji to represent the purpose of the commit. For example, ✨ for adding a new feature or 🔥 for removing something, see the list [here](https://gitmoji.dev/).
***(type)**: Describe the type of change. Common types include `backend`, `frontend`, `CI`, `docker`etc...
***title**: A short, descriptive title for the change.
***description**: Include additional details about what was changed and why.
***title**: A short, descriptive title for the change (*)
* **blank line after the commit title
***description**: Include additional details on why you made the changes (**).
(*) ⚠️ **Make sure you add no space between the emoji and the (type) but add a space after the closing parenthesis of the type and use no caps!**
(**) ⚠️ **Commit description message is mandatory and shouldn't be too long**
### Example Commit Message
@@ -66,7 +70,9 @@ Please add a line to the changelog describing your development. The changelog en
It is nice to add information about the purpose of the pull request to help reviewers understand the context and intent of the changes. If you can, add some pictures or a small video to show the changes.
### Don't forget to:
-check your commits
-signoff your commits
- sign your commits with your key (SSH, GPG etc.)
- check your commits (see warnings above)
- check the linting: `make lint && make frontend-lint`
- check the tests: `make test`
- add a changelog entry
@@ -86,3 +92,11 @@ Make sure that all new features or fixes have corresponding tests. Run the test
If you need any help while contributing, feel free to open a discussion or ask for guidance in the issue tracker. We are more than happy to assist!
Thank you for your contributions! 👍
## Contribute to BlockNote
We use [BlockNote](https://www.blocknotejs.org/) for the text editing features of Docs.
If you find and issue with the editor you can [report it](https://github.com/TypeCellOS/BlockNote/issues) directly on their repository.
Please consider contributing to BlockNotejs, as a library, it's useful to many projects not just Docs.
The project is licended with Mozilla Public License Version 2.0 but be aware that [XL packages](https://github.com/TypeCellOS/BlockNote/blob/main/packages/xl-docx-exporter/LICENSE) are dual licenced with GNU AFFERO GENERAL PUBLIC LICENCE Version 3 and proprietary licence if you are [sponsor](https://www.blocknotejs.org/pricing).
⚠️ **Note that Docs provides docs/pdf exporters by loading [two BlockNote packages](https://github.com/suitenumerique/docs/blob/main/src/frontend/apps/impress/package.json#L22C7-L23C53), which we use under the AGPL-3.0 licence. Until we comply with the terms of this license, we recommend that you don't run Docs as a commercial product, unless you are willing to sponsor [BlockNote](https://github.com/TypeCellOS/BlockNote).**
Docs is a collaborative text editor designed to address common challenges in knowledge building and sharing.
### Write
* 😌 Simple collaborative editing without the formatting complexity of markdown
* 🔌 Offline? No problem, keep writing, your edits will get synced when back online
* 💅 Create clean documents with limited but beautiful formatting options and focus on content
* 🧱 Built for productivity (markdown support, many block types, slash commands, keyboard shortcuts).
* ✨ Save time thanks to our AI actions (generate, sum up, correct, translate)
*😌 Get simple, accessible online editing for your team.
*💅 Create clean documents with beautiful formatting options.
*🖌️ Focus on your content using either the in-line editor, or [the Markdown syntax](https://www.markdownguide.org/basic-syntax/).
* 🧱 Quickly design your page thanks to the many block types, accessible from the `/` slash commands, as well as keyboard shortcuts.
*🔌 Write offline! Your edits will be synced once you're back online.
* ✨ Save time thanks to our AI actions, such as rephrasing, summarizing, fixing typos, translating, etc. You can even turn your selected text into a prompt!
### Collaborate
* 🤝 Collaborate with your team in real time
* 🔒 Granular access control to ensure your information is secure and only shared with the right people
* 📑 Professional document exports in multiple formats (.odt, .doc, .pdf) with customizable templates
* 📚 Built-in wiki functionality to turn your team's collaborative work into organized knowledge `ETA 02/2025`
### Work together
*🤝 Enjoy live editing! See your team collaborate in real time.
*🔒 Keep your information secure thanks to granular access control. Only share with the right people.
*📑 Export your content in multiple formats (`.odt`, `.docx`, `.pdf`) with customizable templates.
*📚 Turn your team's collaborative work into organized knowledge with Subpages.
### Self-host
* 🚀 Easy to install, scalable and secure alternative to Notion, Outline or Confluence
#### 🚀 Docs is easy to install on your own servers
We use Kubernetes for our [production instance](https://docs.numerique.gouv.fr/) but also support Docker Compose. The community contributed a couple other methods (Nix, YunoHost etc.) check out the [docs](/docs/installation/README.md) to get detailed instructions and examples.
#### 🌍 Known instances
We hope to see many more, here is an incomplete list of public Docs instances. Feel free to make a PR to add ones that are not listed below🙏
| Url | Org | Public |
| --- | --- | ------- |
| [docs.numerique.gouv.fr](https://docs.numerique.gouv.fr/) | DINUM | French public agents working for the central administration and the extended public sphere. ProConnect is required to login in or sign up|
| [docs.suite.anct.gouv.fr](https://docs.suite.anct.gouv.fr/) | ANCT | French public agents working for the territorial administration and the extended public sphere. ProConnect is required to login in or sign up|
| [notes.demo.opendesk.eu](https://notes.demo.opendesk.eu) | ZenDiS | Demo instance of OpenDesk. Request access to get credentials |
| [notes.liiib.re](https://notes.liiib.re/) | lasuite.coop | Free and open demo to all. Content and accounts are reset after one month |
| [docs.federated.nexus](https://docs.federated.nexus/) | federated.nexus | Public instance, but you have to [sign up for a Federated Nexus account](https://federated.nexus/register/). |
| [docs.demo.mosacloud.eu](https://docs.demo.mosacloud.eu/) | mosa.cloud | Demo instance of mosa.cloud, a dutch company providing services around La Suite apps. |
#### ⚠️ Advanced features
For some advanced features (ex: Export as PDF) Docs relies on XL packages from BlockNote. These are licenced under GPL and are not MIT compatible. You can perfectly use Docs without these packages by setting the environment variable `PUBLISH_AS_MIT` to true. That way you'll build an image of the application without the features that are not MIT compatible. Read the [environment variables documentation](/docs/env.md) for more information.
## Getting started 🔧
### Test it
Test Docs on your browser by visiting this [demo document](https://impress-preprod.beta.numerique.gouv.fr/docs/6ee5aac4-4fb9-457d-95bf-bb56c2467713/)
You can test Docs on your browser by visiting this [demo document](https://impress-preprod.beta.numerique.gouv.fr/docs/6ee5aac4-4fb9-457d-95bf-bb56c2467713/)
### Run it locally
### 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 but you can choose any S3compatible object storage of your choice.
> ⚠️ The methods described below for running Docs locally is **for testing purposes only**. It is based on building Docs using [Minio](https://min.io/) as an S3-compatible storage solution. Of course you can choose any S3-compatible storage solution.
**Prerequisite**
Make sure you have a recent version of Docker and [Docker Compose](https://docs.docker.com/compose/install) installed on your laptop:
Make sure you have a recent version of Docker and [Docker Compose](https://docs.docker.com/compose/install) installed on your laptop, then type:
```shellscript
$ docker -v
@@ -68,7 +92,7 @@ $ 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.
> ⚠️ You may need to run the following commands with `sudo`, but this can be avoided by adding your user to the local `docker` group.
**Project bootstrap**
@@ -78,20 +102,20 @@ The easiest way to start working on the project is to use [GNU Make](https://www
$ 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.
This command builds the `app-dev` and `frontend-dev` containers, installs dependencies, performs database migrations and compiles 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 can access the project by going to <http://localhost:3000>.
You will be prompted to log in, the default credentials are:
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:
📝 Note that if you need to run them afterwards, you can use the eponymous Make rule:
```shellscript
$ make run
@@ -117,14 +141,21 @@ To start all the services, except the frontend container, you can use the follow
$ make run-backend
```
To execute frontend tests & linting only
```shellscript
$ make frontend-test
$ make frontend-lint
```
**Adding content**
You can create a basic demo site by running:
You can create a basic demo site by running this command:
```shellscript
$ make demo
```
Finally, you can check all available Make rules using:
Finally, you can check all available Make rules using this command:
```shellscript
$ make help
@@ -132,7 +163,7 @@ $ make help
**Django admin**
You can access the Django admin site at
You can access the Django admin site at:
<http://localhost:8071/admin>.
@@ -144,17 +175,17 @@ $ make superuser
## Feedback 🙋♂️🙋♀️
We'd love to hear your thoughts and hear about your experiments, so come and say hi on [Matrix](https://matrix.to/#/#docs-official:matrix.org).
We'd love to hear your thoughts, and hear about your experiments, so come and say hi on [Matrix](https://matrix.to/#/#docs-official:matrix.org).
## Roadmap
## Roadmap 💡
Want to know where the project is headed? [🗺️ Checkout our roadmap](https://github.com/orgs/numerique-gouv/projects/13/views/11)
## Licence 📝
## License 📝
This work is released under the MIT License (see [LICENSE](https://github.com/suitenumerique/docs/blob/main/LICENSE)).
While Docs is a publicdriven initiative our licence choice is an invitation for private sector actors to use, sell and contribute to the project.
While Docs is a public-driven initiative, our license choice is an invitation for private sector actors to use, sell and contribute to the project.
## Contributing 🙌
@@ -162,9 +193,9 @@ This project is intended to be community-driven, so please, do not hesitate to [
You can help us with translations on [Crowdin](https://crowdin.com/project/lasuite-docs).
If you intend to make pull requests see [CONTRIBUTING](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md) for guidelines.
If you intend to make pull requests, see [CONTRIBUTING](https://github.com/suitenumerique/docs/blob/main/CONTRIBUTING.md) for guidelines.
Directory structure:
## Directory structure:
```markdown
docs
@@ -182,14 +213,14 @@ docs
### Stack
Docs is built on top of [Django Rest Framework](https://www.django-rest-framework.org/), [Next.js](https://nextjs.org/), [BlockNote.js](https://www.blocknotejs.org/), [HocusPocus](https://tiptap.dev/docs/hocuspocus/introduction) and [Yjs](https://yjs.dev/).
Docs is built on top of [Django Rest Framework](https://www.django-rest-framework.org/), [Next.js](https://nextjs.org/), [BlockNote.js](https://www.blocknotejs.org/), [HocusPocus](https://tiptap.dev/docs/hocuspocus/introduction) and [Yjs](https://yjs.dev/). We thank the contributors of all these projects for their awesome work!
We are proud sponsors of [BlockNotejs](https://www.blocknotejs.org/) and [Yjs](https://yjs.dev/).
### Gov ❤️ open source
Docs is the result of a joint effort led by the French 🇫🇷🥖 ([DINUM](https://www.numerique.gouv.fr/dinum/)) and German 🇩🇪🥨 governments ([ZenDiS](https://zendis.de/)).
We are proud sponsors of [BlockNotejs](https://www.blocknotejs.org/) and [Yjs](https://yjs.dev/).
We are always looking for new public partners (we are currently onboarding the Netherlands 🇳🇱🧀), feel free to [reach out](mailto:docs@numerique.gouv.fr) if you are interested in using or contributing to Docs.
If you have any issue regarding security, please disclose the information responsibly submiting [this form](https://vdp.numerique.gouv.fr/p/Send-a-report?lang=en) and not by creating an issue on the repository. You can also email us at docs@numerique.gouv.fr
If you have any issue regarding security, please disclose the information responsibly submitting [this form](https://vdp.numerique.gouv.fr/p/Send-a-report?lang=en) and not by creating an issue on the repository. You can also email us at docs@numerique.gouv.fr
We appreciate your effort to make Docs more secure.
@@ -16,6 +16,38 @@ the following command inside your docker container:
## [Unreleased]
## [4.0.0] - 2025-11-26
- ⚠️ We updated `@gouvfr-lasuite/ui-kit` to `0.18.0`, so if you are customizing Docs with a css layer or with a custom template, you need to update your customization to follow the new design system structure.
More information about the changes in the design system can be found here:
- If you were using the `THEME_CUSTOMIZATION_FILE_PATH` and have overridden the header logo, you need to update your customization file to follow the new structure of the header, it is now:
```json
{
...,
"header": {
"icon": {
"src": "your_logo_src",
"width": "your_logo_width",
"height": "your_logo_height"
}
}
}
```
## [3.3.0] - 2025-05-22
⚠️ For some advanced features (ex: Export as PDF) Docs relies on XL packages from BlockNote. These are licenced under AGPL-3.0 and are not MIT compatible. You can perfectly use Docs without these packages by setting the environment variable `PUBLISH_AS_MIT` to true. That way you'll build an image of the application without the features that are not MIT compatible. Read the [environment variables documentation](/docs/env.md) for more information.
The footer is now configurable from a customization file. To override the default one, you can
use the `THEME_CUSTOMIZATION_FILE_PATH` environment variable to point to your customization file.
The customization file must be a JSON file and must follow the rules described in the
[theming documentation](docs/theming.md).
## [3.0.0] - 2025-03-28
We are not using the nginx auth request anymore to access the collaboration server (`yProvider`)
To use this feature, simply set the `FRONTEND_CSS_URL` environment variable to the URL of your custom CSS file. For example:
```javascript
FRONTEND_CSS_URL=http://anything/custom-style.css
```
Once you've set this variable, Docs will load your custom CSS file and apply the styles to our frontend application.
### Benefits
This feature provides several benefits, including:
***Easy customization** 🔄: With this feature, you can easily customize the look and feel of our application without requiring any code changes.
***Flexibility** 🌈: You can use any CSS styles you like to create a custom theme that meets your needs.
***Runtime theming** ⏱️: This feature allows you to change the theme of our application at runtime, without requiring a restart or recompilation.
### Example Use Case
Let's say you want to change the background color of our application to a custom color. You can create a custom CSS file with the following contents:
```css
body{
background-color:#3498db;
}
```
Then, set the `FRONTEND_CSS_URL` environment variable to the URL of your custom CSS file. Once you've done this, our application will load your custom CSS file and apply the styles, changing the background color to the custom color you specified.
----
## Runtime JavaScript Injection 🚀
### How to Use
To use this feature, simply set the `FRONTEND_JS_URL` environment variable to the URL of your custom JavaScript file. For example:
```javascript
FRONTEND_JS_URL=http://anything/custom-script.js
```
Once you've set this variable, Docs will load your custom JavaScript file and execute it in the browser, allowing you to modify the application's behavior at runtime.
### Benefits
This feature provides several benefits, including:
***Dynamic customization** 🔄: With this feature, you can dynamically modify the behavior and appearance of our application without requiring any code changes.
***Flexibility** 🌈: You can add custom functionality, modify existing features, or integrate third-party services.
***Runtime injection** ⏱️: This feature allows you to inject JavaScript into the application at runtime, without requiring a restart or recompilation.
### Example Use Case
Let's say you want to add a custom menu to the application header. You can create a custom JavaScript file with the following contents:
Then, set the `FRONTEND_JS_URL` environment variable to the URL of your custom JavaScript file. Once you've done this, our application will load your custom JavaScript file and execute it, adding your custom menu to the header.
----
## **Your Docs icon** 📝
You can add your own Docs icon in the header from the theme customization file.
### Settings 🔧
```shellscript
THEME_CUSTOMIZATION_FILE_PATH=<path>
```
### Example of JSON
You can activate it with the `header.icon` configuration: https://github.com/suitenumerique/docs/blob/main/src/helm/env.d/dev/configuration/theme/demo.json
This configuration is optional. If not set, the default icon will be used.
----
## **Footer Configuration** 📝
The footer is configurable from the theme customization file.
### Settings 🔧
```shellscript
THEME_CUSTOMIZATION_FILE_PATH=<path>
```
### Example of JSON
The json must follow some rules: https://github.com/suitenumerique/docs/blob/main/src/helm/env.d/dev/configuration/theme/demo.json
`footer.default` is the fallback if the language is not supported.
---
Below is a visual example of a configured footer ⬇️:
| DJANGO_EMAIL_BRAND_NAME | Brand name for email | |
| DJANGO_EMAIL_FROM | Email address used as sender | from@example.com |
| DJANGO_EMAIL_HOST | Hostname of email | |
| DJANGO_EMAIL_HOST_PASSWORD | Password to authenticate with on the email host | |
| DJANGO_EMAIL_HOST_USER | User to authenticate with on the email host | |
| DJANGO_EMAIL_LOGO_IMG | Logo for the email | |
| DJANGO_EMAIL_PORT | Port used to connect to email host | |
| DJANGO_EMAIL_URL_APP | Url used in the email to go to the app | |
| DJANGO_EMAIL_USE_SSL | Use ssl for email host connection | false |
| DJANGO_EMAIL_USE_TLS | Use tls for email host connection | false |
| DJANGO_SECRET_KEY | Secret key | |
| DJANGO_SERVER_TO_SERVER_API_TOKENS | | [] |
| DOCSPEC_API_URL | URL to endpoint of DocSpec conversion API | |
| DOCUMENT_IMAGE_MAX_SIZE | Maximum size of document in bytes | 10485760 |
| FRONTEND_CSS_URL | To add a external css file to the app | |
| FRONTEND_JS_URL | To add a external js file to the app | |
| FRONTEND_HOMEPAGE_FEATURE_ENABLED | Frontend feature flag to display the homepage | false |
| FRONTEND_THEME | Frontend theme to use | |
| LANGUAGE_CODE | Default language | en-us |
| LANGFUSE_SECRET_KEY | The Langfuse secret key used by the sdk | None |
| LANGFUSE_PUBLIC_KEY | The Langfuse public key used by the sdk | None |
| LANGFUSE_BASE_URL | The Langfuse base url used by the sdk | None |
| LASUITE_MARKETING_BACKEND | Backend used when SIGNUP_NEW_USER_TO_MARKETING_EMAIL is True. See https://github.com/suitenumerique/django-lasuite/blob/main/documentation/how-to-use-marketing-backend.md | lasuite.marketing.backends.dummy.DummyBackend |
| LASUITE_MARKETING_PARAMETERS | The parameters to configure LASUITE_MARKETING_BACKEND. See https://github.com/suitenumerique/django-lasuite/blob/main/documentation/how-to-use-marketing-backend.md | {} |
| LOGGING_LEVEL_LOGGERS_APP | Application logging level. options are "DEBUG", "INFO", "WARN", "ERROR", "CRITICAL" | INFO |
| LOGGING_LEVEL_LOGGERS_ROOT | Default logging level. options are "DEBUG", "INFO", "WARN", "ERROR", "CRITICAL" | INFO |
| LOGIN_REDIRECT_URL | Login redirect url | |
| LOGIN_REDIRECT_URL_FAILURE | Login redirect url on failure | |
| LOGOUT_REDIRECT_URL | Logout redirect url | |
| MALWARE_DETECTION_BACKEND | The malware detection backend use from the django-lasuite package | lasuite.malware_detection.backends.dummy.DummyBackend |
| MALWARE_DETECTION_PARAMETERS | A dict containing all the parameters to initiate the malware detection backend | {"callback_path": "core.malware_detection.malware_detection_callback",} |
| MEDIA_BASE_URL | | |
| NO_WEBSOCKET_CACHE_TIMEOUT | Cache used to store current editor session key when only users without websocket are editing a document | 120 |
| THEME_CUSTOMIZATION_CACHE_TIMEOUT | Cache duration for the customization settings | 86400 |
| THEME_CUSTOMIZATION_FILE_PATH | Full path to the file customizing the theme. An example is provided in src/backend/impress/configuration/theme/default.json | BASE_DIR/impress/configuration/theme/default.json |
If you want to build the front-end application using the yarn build command, you can edit the file `src/frontend/apps/impress/.env` with the `NODE_ENV=production` environment variable and modify it. Alternatively, you can use the listed environment variables with the prefix `NEXT_PUBLIC_` (for example, `NEXT_PUBLIC_PUBLISH_AS_MIT=false`).
In `.env.development`, `PUBLISH_AS_MIT` is set to `false`, allowing developers to test Docs with all its features.
⚠️ If you run Docs in production with `PUBLISH_AS_MIT` set to `false` make sure you fulfill your BlockNote licensing or [subscription](https://www.blocknotejs.org/about#partner-with-us) obligations.
> We provide those instructions as an example, for production environments, you should follow the [official documentation](https://www.keycloak.org/documentation).
The following variables need to be updated with your own values, others can be left as is:
```env
POSTGRES_PASSWORD=<generate postgres password>
KC_HOSTNAME=https://id.yourdomain.tld # Change with your own URL
KC_BOOTSTRAP_ADMIN_PASSWORD=<generate your password>
```
### Step 3: Expose keycloak instance on https
> \[!NOTE\]
> You can skip this section if you already have your own setup.
To access your Keycloak instance on the public network, it needs to be exposed on a domain with SSL termination. You can use our [example with nginx proxy and Let's Encrypt companion](../nginx-proxy/README.md) for automated creation/renewal of certificates using [acme.sh](http://acme.sh).
If following our example, uncomment the environment and network sections in compose file and update it with your values.
```yaml
version:'3'
services:
keycloak:
...
# Uncomment and set your values if using our nginx proxy example
# environment:
# - VIRTUAL_HOST=id.yourdomain.tld # used by nginx proxy
# - VIRTUAL_PORT=8080 # used by nginx proxy
# - LETSENCRYPT_HOST=id.yourdomain.tld # used by lets encrypt to generate TLS certificate
...
# Uncomment if using our nginx proxy example
# networks:
# - proxy-tier
# - default
# Uncomment if using our nginx proxy example
#networks:
# proxy-tier:
# external: true
```
### Step 4: Start the service
```bash
`docker compose up -d`
```
Your keycloak instance is now available on https://doc.yourdomain.tld
## Creating an OIDC Client for Docs Application
### Step 1: Create a New Realm
1. Log in to the Keycloak administration console.
2. Navigate to the realm tab and click on the "Create realm" button.
3. Enter the name of the realm - `docs`.
4. Click "Create".
#### Step 2: Create a New Client
1. Navigate to the "Clients" tab.
2. Click on the "Create client" button.
3. Enter the client ID - e.g. `docs`.
4. Enable "Client authentication" option.
6. Set the "Valid redirect URIs" to the URL of your docs application suffixed with `/*` - e.g., "https://docs.example.com/*".
1. Set the "Web Origins" to the URL of your docs application - e.g. `https://docs.example.com`.
1. Click "Save".
#### Step 3: Get Client Credentials
1. Go to the "Credentials" tab.
2. Copy the client ID (`docs` in this example) and the client secret.
> We provide those instructions as an example, it should not be run in production. For production environments, deploy MinIO [in a Multi-Node Multi-Drive (Distributed)](https://min.io/docs/minio/linux/operations/install-deploy-manage/deploy-minio-multi-node-multi-drive.html#minio-mnmd) topology
### Step 2:. Update compose file with your own values
```yaml
version:'3'
services:
minio:
...
environment:
- MINIO_ROOT_USER=<Set minio root username>
- MINIO_ROOT_PASSWORD=<Set minio root password>
```
### Step 3: Expose MinIO instance
#### Option 1: Internal network
You may not need to expose your MinIO instance to the public if only services hosted on the same private network need to access to your MinIO instance.
You should create a docker network that will be shared between those services
```bash
docker network create storage-tier
```
#### Option 2: Public network
If you want to expose your MinIO instance to the public, it needs to be exposed on a domain with SSL termination. You can use our [example](../nginx-proxy/README.md) with an nginx proxy and Let's Encrypt companion for automated creation/renewal of Let's Encrypt certificates using [acme.sh](http://acme.sh).
If following our example, uncomment the environment and network sections in compose file and update it with your values.
```yaml
version:'3'
services:
docs:
...
minio:
...
environment:
...
# - VIRTUAL_HOST=storage.yourdomain.tld # used by nginx proxy
# - VIRTUAL_PORT=9000 # used by nginx proxy
# - LETSENCRYPT_HOST=storage.yourdomain.tld # used by lets encrypt to generate TLS certificate
...
# Uncomment if using our nginx proxy example
# networks:
# - proxy-tier
# - default
# Uncomment if using our nginx proxy example
#networks:
# proxy-tier:
# external: true
```
In this example we are only exposing MinIO API service. Follow the official documentation to configure Minio WebUI.
### Step 4: Start the service
```bash
`docker compose up -d`
```
Your minio instance is now available on https://storage.yourdomain.tld
## Creating a user and bucket for your Docs instance
### Installing mc
Follow the [official documentation](https://min.io/docs/minio/linux/reference/minio-mc.html#install-mc) to install mc
### Step 1: Configure `mc` to connect to your MinIO Server with your root user
```shellscript
mc alias set minio <MINIO_SERVER_URL> <MINIO_ROOT_USER> <MINIO_ROOT_PASSWORD>
```
Replace the values with those you have set in the previous steps
### Step 2: Create a new bucket with versioning enabled
```shellscript
mc mb --with-versioning minio/<your-bucket-name>
```
Replace `your-bucket-name` with the desired name for your bucket e.g. `docs-media-storage`
### Additional notes:
For increased security you should create a dedicated user with `readwrite` access to the Bucket. In the following example we will use MinIO root user.
> We provide those instructions as an example, for extended development or production environments, you should follow the [official documentation](https://github.com/nginx-proxy/acme-companion/tree/main/docs).
Nginx-proxy sets up a container running nginx and docker-gen. docker-gen generates reverse proxy configs for nginx and reloads nginx when containers are started and stopped.
Acme-companion is a lightweight companion container for nginx-proxy. It handles the automated creation, renewal and use of SSL certificates for proxied Docker containers through the ACME protocol.
### Step 2: Edit `DEFAULT_EMAIL` in the compose file.
Albeit optional, it is recommended to provide a valid default email address through the `DEFAULT_EMAIL` environment variable, so that Let's Encrypt can warn you about expiring certificates and allow you to recover your account.
### Step 3: Create docker network
Containers need share the same network for auto-discovery.
```bash
docker network create proxy-tier
```
### Step 4: Start service
```bash
docker compose up -d
```
## Usage
Once both nginx-proxy and acme-companion containers are up and running, start any container you want proxied with environment variables `VIRTUAL_HOST` and `LETSENCRYPT_HOST` both set to the domain(s) your proxied container is going to use.
If you want to install Docs you've come to the right place.
Here are a bunch of resources to help you install the project.
## Kubernetes
We (Docs maintainers) are only using the Kubernetes deployment method in production. We can only provide advanced support for this method.
Please follow the instructions laid out [here](/docs/installation/kubernetes.md).
## Docker Compose
We are aware that not everyone has Kubernetes Cluster laying around 😆.
We also provide [Docker images](https://hub.docker.com/u/lasuite?page=1&search=impress) that you can deploy using Compose.
Please follow the instructions [here](/docs/installation/compose.md).
⚠️ Please keep in mind that we do not use it ourselves in production. Let us know in the issues if you run into troubles, we'll try to help.
## Other ways to install Docs
Community members have contributed several other ways to install Docs. While we owe them a big thanks 🙏, please keep in mind we (Docs maintainers) can't provide support on these installation methods as we don't use them ourselves and there are two many options out there for us to keep track of. Of course you can contact the contributors and the broader community for assistance.
Here is the list of other methods in alphabetical order:
We provide a sample configuration for running Docs using Docker Compose. Please note that this configuration is experimental, and the official way to deploy Docs in production is to use [k8s](../installation/kubernetes.md)
## Requirements
- A modern version of Docker and its Compose plugin.
- A domain name and DNS configured to your server.
- An Identity Provider that supports OpenID Connect protocol - we provide [an example to deploy Keycloak](../examples/compose/keycloak/README.md).
- An Object Storage that implements S3 API - we provide [an example to deploy Minio](../examples/compose/minio/README.md).
- A Postgresql database - we provide [an example in the compose file](../examples/compose/compose.yaml).
- A Redis database - we provide [an example in the compose file](../examples/compose/compose.yaml).
## Software Requirements
Ensure you have Docker Compose(v2) installed on your host server. Follow the official guidelines for a reliable setup:
Docker Compose is included with Docker Engine:
- **Docker Engine:** We suggest adhering to the instructions provided by Docker
for [installing Docker Engine](https://docs.docker.com/engine/install/).
For older versions of Docker Engine that do not include Docker Compose:
- **Docker Compose:** Install it as per the [official documentation](https://docs.docker.com/compose/install/).
> [!NOTE]
> `docker-compose` may not be supported. You are advised to use `docker compose` instead.
Docs configuration is achieved through environment variables. We provide a [detailed description of all variables](../env.md).
In this example, we assume the following services:
- OIDC provider on https://id.yourdomain.tld
- Object Storage on https://storage.yourdomain.tld
- Docs on https://docs.yourdomain.tld
- Bucket name is docs-media-storage
**Set your own values in `env.d/common`**
### OIDC
Authentication in Docs is managed through Open ID Connect protocol. A functional Identity Provider implementing this protocol is required.
For guidance, refer to our [Keycloak deployment example](../examples/compose/keycloak/README.md).
If using Keycloak as your Identity Provider, set `OIDC_RP_CLIENT_ID` and `OIDC_RP_CLIENT_SECRET` variables with those of the OIDC client created for Docs. By default we have set `docs` as the realm name, if you have named your realm differently, update the value `REALM_NAME` in `env.d/common`
For others OIDC providers, update the variables in `env.d/backend`.
### Object Storage
Files and media are stored in an Object Store that supports the S3 API.
For guidance, refer to our [Minio deployment example](../examples/compose/minio/README.md).
Set `AWS_S3_ACCESS_KEY_ID` and `AWS_S3_SECRET_ACCESS_KEY` with the credentials of a user with `readwrite` access to the bucket created for Docs.
### Postgresql
Docs uses PostgreSQL as its database. Although an external PostgreSQL can be used, our example provides a deployment method.
If you are using the example provided, you need to generate a secure key for `DB_PASSWORD` and set it in `env.d/postgresql`.
If you are using an external service or not using our default values, you should update the variables in `env.d/postgresql`
### Redis
Docs uses Redis for caching. While an external Redis can be used, our example provides a deployment method.
If you are using an external service, you need to set `REDIS_URL` environment variable in `env.d/backend`.
### Y Provider
The Y provider service enables collaboration through websockets.
Generates a secure key for `Y_PROVIDER_API_KEY` and `COLLABORATION_SERVER_SECRET` in ``env.d/yprovider``.
### Docs
The Docs backend is built on the Django Framework.
Generates a secure key for `DJANGO_SECRET_KEY` in `env.d/backend`.
### Logging
Update the following variables in `env.d/backend` if you want to change the logging levels:
```env
LOGGING_LEVEL_HANDLERS_CONSOLE=DEBUG
LOGGING_LEVEL_LOGGERS_ROOT=DEBUG
LOGGING_LEVEL_LOGGERS_APP=DEBUG
```
### Mail
The following environment variables are required in `env.d/backend` for the mail service to send invitations :
```env
DJANGO_EMAIL_HOST=<smtp host>
DJANGO_EMAIL_HOST_USER=<smtp user>
DJANGO_EMAIL_HOST_PASSWORD=<smtp password>
DJANGO_EMAIL_PORT=<smtp port>
DJANGO_EMAIL_FROM=<your email address>
#DJANGO_EMAIL_USE_TLS=true # A flag to enable or disable TLS for email sending.
#DJANGO_EMAIL_USE_SSL=true # A flag to enable or disable SSL for email sending.
DJANGO_EMAIL_BRAND_NAME=<brand name used in email templates> # e.g. "La Suite Numérique"
DJANGO_EMAIL_LOGO_IMG=<logo image to use in email templates.> # e.g. "https://docs.yourdomain.tld/assets/logo-suite-numerique.png"
DJANGO_EMAIL_URL_APP=<url used in email templates to go to the app> # e.g. "https://docs.yourdomain.tld"
```
### AI
Built-in AI actions let users generate, summarize, translate, and correct content.
AI is disabled by default. To enable it, the following environment variables must be set in in `env.d/backend`:
```env
AI_FEATURE_ENABLED=true # is false by default
AI_BASE_URL=https://openaiendpoint.com
AI_API_KEY=<API key>
AI_MODEL=<model used> e.g. llama
```
### Frontend theme
You can [customize your Docs instance](../theming.md) with your own theme and custom css.
The following environment variables must be set in `env.d/backend`:
```env
FRONTEND_THEME=default # name of your theme built with cuningham
> In a production environment, configure SSL/TLS termination to run your instance on https.
If you have your own certificates and proxy setup, you can skip this part.
You can follow our [nginx proxy example](../examples/compose/nginx-proxy/README.md) with automatic generation and renewal of certificate with Let's Encrypt.
You will need to uncomment the environment and network sections in compose file and update it with your values.
```yaml
frontend:
...
# Uncomment and set your values if using our nginx proxy example
#environment:
# - VIRTUAL_HOST=${DOCS_HOST} # used by nginx proxy
# - VIRTUAL_PORT=8083 # used by nginx proxy
# - LETSENCRYPT_HOST=${DOCS_HOST} # used by lets encrypt to generate TLS certificate
...
# Uncomment if using our nginx proxy example
# networks:
# - proxy-tier
#
#networks:
# proxy-tier:
# external: true
```
## Step 4: Start Docs
You are ready to start your Docs application !
```bash
docker compose up -d
```
> [!NOTE]
> Version of the images are set to latest, you should pin it to the desired version to avoid unwanted upgrades when pulling latest image.
## Step 5: Run the database migration and create Django admin user
```bash
docker compose run --rm backend python manage.py migrate
@@ -7,7 +7,7 @@ This document is a step-by-step guide that describes how to install Docs on a k8
- k8s cluster with an nginx-ingress controller
- an OIDC provider (if you don't have one, we provide an example)
- a PostgreSQL server (if you don't have one, we provide an example)
- a Memcached server (if you don't have one, we provide an example)
- a Redis server (if you don't have one, we provide an example)
- a S3 bucket (if you don't have one, we provide an example)
### Test cluster
@@ -100,116 +100,137 @@ When your k8s cluster is ready (the ingress nginx controller is up), you can sta
Please remember that `*.127.0.0.1.nip.io` will always resolve to `127.0.0.1`, except in the k8s cluster where we configure CoreDNS to answer with the ingress-nginx service IP.
The namespace `impress` is already created, you can work in it and configure your kubectl cli to use it by default.
We provide our own helm chart for all development dependencies, it is available here https://github.com/suitenumerique/helm-dev-backend
This provided chart is for development purpose only and is not ready to use in production.
You can install it on your cluster to deploy keycloak, minio, postgresql and redis.
### What do you use to authenticate your users?
Docs uses OIDC, so if you already have an OIDC provider, obtain the necessary information to use it. In the next step, we will see how to configure Django (and thus Docs) to use it. If you do not have a provider, we will show you how to deploy a local Keycloak instance (this is not a production deployment, just a demo).
Docs uses a postgresql database as backend, so if you have a provider, obtain the necessary information to use it. If you don't, you can install a postgresql testing environment as follow:
Docs uses a postgresql database as backend, so if you have a provider, obtain the necessary information to use it. If you don't, you can install a postgresql testing environment as follow:
From here the important information you will need are:
```yaml
DB_HOST: postgresql-dev-backend-postgres
DB_NAME:
secretKeyRef:
name: postgresql-dev-backend-postgres
key: database
DB_USER:
secretKeyRef:
name: postgresql-dev-backend-postgres
key: username
DB_PASSWORD:
secretKeyRef:
name: postgresql-dev-backend-postgres
key: password
DB_PORT: 5432
```
### Find s3 bucket connection values
Docs uses an s3 bucket to store documents, so if you have a provider obtain the necessary information to use it. If you don't, you can install a local minio testing environment as follow:
Now you are ready to deploy Docs without AI. AI requires more dependencies (OpenAI API). To deploy Docs you need to provide all previous informations to the helm chart.
Now you are ready to deploy Docs without AI. AI requires more dependencies (OpenAI API). To deploy Docs you need to provide all previous information to the helm chart.
This document explains how to configure and override the available languages in the Docs application.
## Default Languages
By default, the application supports the following languages (in priority order):
- English (en-us)
- French (fr-fr)
- German (de-de)
- Dutch (nl-nl)
- Spanish (es-es)
The default configuration is defined in `src/backend/impress/settings.py`:
```python
LANGUAGES=values.SingleNestedTupleValue(
(
("en-us","English"),
("fr-fr","Français"),
("de-de","Deutsch"),
("nl-nl","Nederlands"),
("es-es","Español"),
)
)
```
## Overriding Languages
### Using Environment Variables
You can override the available languages by setting the `DJANGO_LANGUAGES` environment variable. This is the recommended approach for customizing language support without modifying the source code.
#### Format
The `DJANGO_LANGUAGES` variable expects a semicolon-separated list of language configurations, where each language is defined as `code,Display Name`:
- Use lowercase for language codes and region identifiers
### Priority Order
Languages are listed in priority order. The first language in the list is used as the fallback language throughout the application when a specific translation is not available.
### Translation Availability
Before adding a new language, ensure that:
1. Translation files exist for that language in the `src/backend/locale/` directory
2. The frontend application has corresponding translation files
3. All required messages have been translated
#### Available Languages
The following languages have translation files available in `src/backend/locale/`:
-`br_FR` - Breton (France)
-`cn_CN` - Chinese (China) - *Note: Use `zh-cn` in DJANGO_LANGUAGES*
-`de_DE` - German (Germany) - Use `de-de`
-`en_US` - English (United States) - Use `en-us`
-`es_ES` - Spanish (Spain) - Use `es-es`
-`fr_FR` - French (France) - Use `fr-fr`
-`it_IT` - Italian (Italy) - Use `it-it`
-`nl_NL` - Dutch (Netherlands) - Use `nl-nl`
-`pt_PT` - Portuguese (Portugal) - Use `pt-pt`
-`ru_RU` - Russian (Russia) - Use `ru-ru`
-`sl_SI` - Slovenian (Slovenia) - Use `sl-si`
-`sv_SE` - Swedish (Sweden) - Use `sv-se`
-`tr_TR` - Turkish (Turkey) - Use `tr-tr`
-`uk_UA` - Ukrainian (Ukraine) - Use `uk-ua`
-`zh_CN` - Chinese (China) - Use `zh-cn`
**Note:** When configuring `DJANGO_LANGUAGES`, use lowercase with hyphens (e.g., `pt-pt`, `ru-ru`) rather than the directory name format.
### Translation Management
We use [Crowdin](https://crowdin.com/) to manage translations for the Docs application. Crowdin allows our community to contribute translations and helps maintain consistency across all supported languages.
**Want to add a new language or improve existing translations?**
If you would like us to support a new language or want to contribute to translations, please get in touch with the project maintainers. We can add new languages to our Crowdin project and coordinate translation efforts with the community.
### Cookie and Session
The application stores the user's language preference in a cookie named `docs_language`. The cookie path is set to `/` by default.
## Testing Language Configuration
After changing the language configuration:
1. Restart the application services
2. Verify the language selector displays the correct languages
3. Test switching between different languages
4. Confirm that content is displayed in the selected language
## Troubleshooting
### Languages not appearing
- Verify the environment variable is correctly formatted (semicolon-separated, comma between code and name)
- Check that there are no trailing spaces in language codes or names
- Ensure the application was restarted after changing the configuration
### Missing translations
If you add a new language but see untranslated text:
1. Check if translation files exist in `src/backend/locale/<language_code>/LC_MESSAGES/`
2. Run Django's `makemessages` and `compilemessages` commands to generate/update translations
3. Verify frontend translation files are available
## Related Configuration
-`LANGUAGE_CODE`: Default language code (default: `en-us`)
-`LANGUAGE_COOKIE_NAME`: Cookie name for storing user language preference (default: `docs_language`)
Memory is the first bottleneck; CPU matters only when Celery or the Next.js build is saturated.
> **Note:** Memory consumption varies by operating system. Windows tends to be more memory-hungry than Linux, so consider adding 10-20% extra RAM when running on Windows compared to Linux-based systems.
**RAM**– start at 8 GB dev / 16 GB staging / 32 GB prod. Postgres and Keycloak are the first to OOM; scale them first.
> **OS considerations:** Windows systems typically require 10-20% more RAM than Linux due to higher OS overhead. Docker Desktop on Windows also uses additional memory compared to native Linux Docker.
**CPU**– budget one vCPU per busy container until Celery or Next.js builds saturate.
**Disk**– SSD; add 10 GB extra for the Docker layer cache.
**MinIO**– for demos, mount a local folder instead of running MinIO to save 2 GB+ of RAM.
To use this feature, simply set the `FRONTEND_CSS_URL` environment variable to the URL of your custom CSS file. For example:
```javascript
FRONTEND_CSS_URL=http://anything/custom-style.css
```
Once you've set this variable, our application will load your custom CSS file and apply the styles to our frontend application.
### Benefits
This feature provides several benefits, including:
***Easy customization** 🔄: With this feature, you can easily customize the look and feel of our application without requiring any code changes.
***Flexibility** 🌈: You can use any CSS styles you like to create a custom theme that meets your needs.
***Runtime theming** ⏱️: This feature allows you to change the theme of our application at runtime, without requiring a restart or recompilation.
### Example Use Case
Let's say you want to change the background color of our application to a custom color. You can create a custom CSS file with the following contents:
```css
body{
background-color:#3498db;
}
```
Then, set the `FRONTEND_CSS_URL` environment variable to the URL of your custom CSS file. Once you've done this, our application will load your custom CSS file and apply the styles, changing the background color to the custom color you specified.
This project uses **LF (Line Feed: `\n`) line endings** exclusively. Windows users may encounter issues because:
- **Windows** defaults to CRLF (Carriage Return + Line Feed: `\r\n`) for line endings
- **This project** uses LF line endings for consistency across all platforms
- **Git** may automatically convert line endings, causing conflicts or build failures
### Common Symptoms
- Git shows files as modified even when no changes were made
- Error messages like "warning: LF will be replaced by CRLF"
- Build failures or linting errors due to line ending mismatches
### Solutions for Windows Users
#### Configure Git to Preserve LF (Recommended)
Configure Git to NOT convert line endings and preserve LF:
```bash
git config core.autocrlf false
git config core.eol lf
```
This tells Git to:
- Never convert line endings automatically
- Always use LF for line endings in working directory
#### Fix Existing Repository with Wrong Line Endings
If you already have CRLF line endings in your local repository, the **best approach** is to configure Git properly and clone the project again:
1.**Configure Git first**:
```bash
git config --global core.autocrlf false
git config --global core.eol lf
```
2. **Clone the project fresh** (recommended):
```bash
# Navigate to parent directory
cd ..
# Remove current repository (backup your changes first!)
rm -rf docs
# Clone again with correct line endings
git clone git@github.com:suitenumerique/docs.git
```
**Alternative**: If you have uncommitted changes and cannot re-clone:
1. **Backup your changes**:
```bash
git add .
git commit -m "Save changes before fixing line endings"
```
2. **Remove all files from Git's index**:
```bash
git rm --cached -r .
```
3. **Reset Git configuration** (if not done globally):
```bash
git config core.autocrlf false
git config core.eol lf
```
4. **Re-add all files** (Git will use LF line endings):
```bash
git add .
```
5. **Commit the changes**:
```bash
git commit -m "✏️(project) Fix line endings to LF"
```
## Frontend File Watching Issues on Windows
### Problem Description
Windows users may experience issues with file watching in the frontend-development container. This typically happens because:
- **Docker on Windows** has known limitations with file change detection
- **Node.js file watchers** may not detect changes properly on Windows filesystem
- **Hot reloading** fails to trigger when files are modified
### Common Symptoms
- Changes to frontend code aren't detected automatically
- Hot module replacement doesn't work as expected
- Need to manually restart the frontend container after code changes
- Console shows no reaction when saving files
### Solution: Enable WATCHPACK_POLLING
Add the `WATCHPACK_POLLING=true` environment variable to the frontend-development service in your local environment:
1. **Modify the `compose.yml` file** by adding the environment variable to the frontend-development service:
```yaml
frontend-development:
user: "${DOCKER_USER:-1000}"
build:
context: .
dockerfile: ./src/frontend/Dockerfile
target: impress-dev
args:
API_ORIGIN: "http://localhost:8071"
PUBLISH_AS_MIT: "false"
SW_DEACTIVATED: "true"
image: impress:frontend-development
environment:
- WATCHPACK_POLLING=true # Add this line for Windows users
volumes:
- ./src/frontend:/home/frontend
- /home/frontend/node_modules
- /home/frontend/apps/impress/node_modules
ports:
- "3000:3000"
```
2. **Restart your containers**:
```bash
make run
```
### Why This Works
- `WATCHPACK_POLLING=true` forces the file watcher to use polling instead of filesystem events
- Polling periodically checks for file changes rather than relying on OS-level file events
- This is more reliable on Windows but slightly increases CPU usage
- Changes to your frontend code should now be detected properly, enabling hot reloading
### Note
This setting is primarily needed for Windows users. Linux and macOS users typically don't need this setting as file watching works correctly by default on those platforms.
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.