Commit Graph

112 Commits

Author SHA1 Message Date
claude_code 46688074d8 Merge pull request 'feat(tree): server-authoritative realtime tree updates' (#15) from feat/realtime-tree-server into develop 2026-06-20 19:48:36 +03:00
vvzvlad f650d2591b fix(tree): address realtime-tree-server review findings
- make addTreeNode receivers idempotent (invalidateOnCreatePage guard +
  buildTree dedup) so the author's self-echo no longer duplicates the node
- broadcast realtime tree updates for bulk copy/duplicate and import via a
  root refetch: PAGE_CREATED now carries spaceId and the WS listener falls
  back to refetchRootTreeNodeEvent when no per-node snapshot is present
- remove the now-dead client-relay inbound path (isTreeEvent/handleTreeEvent)
  that remained a stale-restriction-cache attack surface
- honest string|null cast for a root move's parent id
- add tests: buildTree dedup; onPageCreated per-node vs refetch branching

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 19:48:06 +03:00
claude_code b20ffd1b91 Merge pull request 'feat(tree): Expand all / Collapse all for the space page tree' (#23) from feat/tree-expand-collapse-all-agent227 into develop 2026-06-20 17:40:29 +03:00
vvzvlad 234ae759f5 refactor(tree): borrow cleanups from the sibling expand-all impl
- extract collectAllIds / collectBranchIds into tree/utils and use them in
  space-tree.tsx instead of inline closures
- drop the duplicate SidebarPageTreeDto, reuse the existing SidebarPageDto
  for the /pages/tree endpoint
- type the getSpaceTree client call as api.post<{ items: IPage[] }>

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 17:39:34 +03:00
claude code agent 180 36ae4bd3d3 feat(page-tree): gate compact tree density behind COMPACT_PAGE_TREE flag
Make the denser page-tree layout opt-in instead of hardcoded, so row
density can be toggled per deployment via the COMPACT_PAGE_TREE runtime
config flag.

- doc-tree: extract ROW_HEIGHT_STANDARD (32) / ROW_HEIGHT_COMPACT (26);
  default the virtualizer row stride to STANDARD density.
- client: isCompactPageTreeEnabled() in lib/config (reads
  COMPACT_PAGE_TREE, default true); used by space-tree and shared-tree
  to choose the row height.
- server: EnvironmentService.isCompactPageTreeEnabled() and expose
  COMPACT_PAGE_TREE through the window runtime config (static.module).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 16:54:09 +03:00
claude code agent 227 5d5f61fc6e fix(tree): place remote moves by position; remove stale node on move-into-restricted
Release-cycle review found two move-path issues:
- Remote moves were placed at index:0 (broadcastPageMoved hardcodes index:0),
  so every observer rendered the moved node at the TOP of its new siblings
  until refetch. Client moveTreeNode now places by fractional position
  (treeModel.placeByPosition, mirroring addTreeNode/insertByPosition) and
  applies the payload's pageData (title->name, icon, hasChildren) so receivers
  keep the node correct.
- Moving a page under a restricted ancestor left a stale named node (title/
  slugId/icon) in the trees of users who lost visibility. broadcastPageMoved
  now derives one FRESH hasRestrictedAncestor decision and drives both paths
  from it: when restricted, the move goes to authorized users only
  (emitToAuthorizedUsers, not the space-cache-gated emitTreeEvent) and a
  compensating deleteTreeNode goes to the unauthorized complement (same fresh
  getUserIdsWithPageAccess set) — disjoint, no stale-cache window. Non-restricted
  moves are unchanged (one moveTreeNode to the room).

Follow-up (noted): invalidateSpaceRestrictionCache is still unwired at
permission-mutation sites; the open-space fast path can lag up to the 30s TTL,
but the move/delete consistency above no longer depends on it.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 14:01:37 +03:00
claude code agent 227 046132afc7 feat(tree): server-authoritative realtime tree updates
The sidebar page tree only updated on other clients when a change was made
via the UI tree, in an open tab, within a ~50ms client relay window — API/MCP/
AI/import changes never propagated. Move the source of truth to the server.

Server:
- Enrich PageEvent with thin TreeNodeSnapshot(s) so the WS listener never reads
  the DB (avoids the in-transaction visibility race). insertPage fills the
  create snapshot from its returning() row; removePage ships only the deleted
  subtree ROOT (client treeModel.remove drops descendants); restorePage carries
  spaceId.
- New PAGE_MOVED event from movePage with old/new parent + position + snapshot
  (generic PAGE_UPDATED stays for content/rename).
- WsService.emitTreeEvent mirrors emitCommentEvent (per-space restriction gate:
  spaceHasRestrictions -> hasRestrictedAncestor -> broadcastToAuthorizedUsers);
  author NOT excluded so non-UI creators see their own page (receiver is
  idempotent).
- WsTreeService.broadcastPageCreated/Deleted/Moved + broadcastRefetchRoot;
  new PageWsListener (create/delete/move/restore) registered in WsModule.

Client:
- Remove the client relay (emit + setTimeout(50)) from create/move/delete;
  keep optimistic local updates. Make the optimistic create insert id-idempotent
  (find-then-skip) so the now-fast server addTreeNode broadcast can't race it
  into a duplicate row. addTreeNode inserts by fractional position among loaded
  siblings (consistent order across clients).

Restore uses refetchRootTreeNodeEvent (robust for subtree re-attach). Rename/icon
updateOne and cross-space move realtime are deferred (commented as follow-ups).

Implements docs/backlog/realtime-tree-server-authoritative.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 08:27:56 +03:00
claude code agent 227 b81819ef63 feat(tree): Expand all / Collapse all for the space page tree
Adds a server-authoritative whole-tree endpoint and sidebar menu commands
so a deep space tree can be expanded in one request instead of a per-level
BFS storm.

Server:
- POST /pages/tree (SidebarPageTreeDto: spaceId | pageId), same CASL space
  scoping as /sidebar-pages. Returns the whole space tree / subtree as a flat
  list in the sidebar item shape (id, slugId, title, icon, position,
  parentPageId, spaceId, hasChildren, canEdit), ordered by position
  (collate C byte order), content never fetched.
- page.service.getSidebarPagesTree reproduces getSidebarPages' two-branch
  permission model: open space -> spaceCanEdit; restricted space -> seed the
  full descendant set then prune via filterAccessibleTreePages +
  filterAccessiblePageIdsWithPermissions (keeps restricted-but-granted pages,
  prunes inaccessible subtrees). hasChildren is derived from the final
  filtered set so it can never reveal inaccessible children.
- page.repo.getSpaceDescendants: recursive CTE seeded by space roots.

Client:
- SpaceTree is forwardRef exposing expandAll/collapseAll/isExpanding;
  expandAll fetches the whole tree once, replaces current-space nodes, opens
  every branch (current space only), aborts on space switch, surfaces real
  errors; collapseAll collapses only current-space ids (shared open-map).
- SpaceMenu gains Expand all / Collapse all items (no admin gate).

Implements docs/backlog/tree-expand-collapse-all.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 05:31:34 +03:00
vvzvlad b1d48d9d9a fix(client): compact page tree + fix selection highlight alignment
Reduce DocTree row stride from 32px to 26px for a denser sidebar tree,
and fix the selection/hover highlight that looked unbalanced at the
tighter spacing.

Root causes:
- The virtualized <li> had no explicit height, so `.node`'s height:100%
  collapsed to content height; combined with the asymmetric
  `[role="treeitem"] { padding-bottom: 2px }` rule, row content was
  pushed to the top of the highlight pill (icon glued to the top edge).
- NodeMenu / CreateNode action icons used the default Mantine ActionIcon
  size (md = 28px), overflowing the tighter 26px row stride onto
  neighbouring rows.

Changes:
- doc-tree.tsx: rowHeight 32 -> 26; give each row <li> a definite
  height = rowHeight.
- tree.module.css: rowWrapper fills the slot (height:100%); node pill is
  inset and vertically centered (height: calc(100% - 4px)); drop the
  asymmetric [role="treeitem"] padding-bottom.
- space-tree-node-menu.tsx / space-tree-row.tsx: action icons size={20}.
- share.module.css: drop now-dead .treeNode padding-bottom override.

Verified in an isolated browser harness: highlight content is centered
(2.8/2.8px) and nothing overflows the row stride.
2026-06-18 23:08:42 +03:00
vvzvlad 66bb0813a8 fix(client): tighten page tree vertical density
Reduce DocTree default rowHeight from 32px to 26px so sidebar page
tree rows pack closer together. The virtualizer uses rowHeight as the
row stride (estimateSize + translateY), and row content is only ~22px
tall, so the previous 32px left an ~8px gap between nodes. Both the
space tree and the shared (public) tree inherit the default, so both
become denser and stay consistent.
2026-06-18 20:46:23 +03:00
vvzvlad 8f5be58f9b feat(ai-chat): move AI chat icon into the global top bar
Move the AI-chat toggle icon (IconSparkles) from the page header menu
into the global top bar, placed next to the notifications icon. The
"AI chat enabled" gate (workspace.settings.ai.chat) is preserved, and
the icon style is aligned with the neighbouring notifications icon
(subtle, size sm). As a result the entry point is now available on all
routes instead of only on page routes.

- app-header.tsx: render the gated AI-chat ActionIcon before
  NotificationPopover; wire it to aiChatWindowOpenAtom.
- page-header-menu.tsx: remove the old AI icon block and its now-unused
  imports/locals.
2026-06-18 17:50:42 +03:00
vvzvlad ca0622ef01 feat(client): persist page-tree open/closed state per workspace+user
The sidebar page tree previously kept its expanded/collapsed state in an
in-memory jotai atom, so it reset on every reload. Persist it in
localStorage instead, scoped by `${workspaceId}:${userId}` so multiple
accounts sharing a browser origin don't leak tree state into each other.

- open-tree-nodes-atom: replace the in-memory atom with a facade over an
  atomFamily of atomWithStorage, scoped via currentUserAtom; keep the same
  [OpenMap, functional-updater setter] public API so space-tree needs no
  change.
- Use an explicit synchronous createJSONStorage + getOnInit: true so the
  saved state is read at atom init — no collapse-then-expand flicker on
  reload and no write against an un-hydrated empty map.
- README / README.ru: document persistent page-tree state in the
  "What's different from Docmost" table.
2026-06-18 05:42:12 +03:00
vvzvlad 3806406413 refactor(import): remove non-functional DOCX/PDF/Confluence import buttons
DOCX, PDF and Confluence import relied on a private EE module that was
dropped from this build, so those code paths only threw "enterprise
license" errors (DOCX/PDF) or silently did nothing (Confluence) while the
UI still presented them as working options.

- page-import-modal: drop the Word (DOCX), PDF and Confluence FileButtons
- remove the now-dead icon imports (IconFileTypeDocx, IconFileTypePdf,
  ConfluenceIcon), the docx/pdf/confluence file refs and their input-reset
  branches in handleFileUpload/handleZipUpload
- delete the orphaned confluence-icon.tsx component (no remaining importers)

Markdown, HTML, Notion and the generic zip upload remain unchanged.
2026-06-18 03:50:34 +03:00
vvzvlad 7609538f9c feat(ai-chat): convert AI chat from aside panel to floating window
Replace the docked right-aside AI chat with a floating, draggable,
resizable, minimizable window per the GitmostAgent design. The "AI chat"
entry points (page header menu, page-history item) now open the window
instead of the aside tab.

- Add ai-chat-window.tsx + ai-chat-window.module.css: fixed-position
  window with viewport-clamped drag, CSS resize, minimize (hides body
  via CSS so ChatThread/useChat stays mounted and streaming is not
  aborted), and geometry kept in state (survives close/reopen, re-clamped
  on open via useLayoutEffect, size tracked with a ResizeObserver).
- Reuse ChatThread, ConversationList and the transcript components
  unchanged; move all orchestration (active chat, adopt-new-chat,
  openPage, queries) into the window.
- Header shows a tokens-only badge: sum of persisted metadata.usage for
  the active chat (no cost/context-total data available), hidden at 0.
- Add aiChatWindowOpenAtom; mount the window once in global-app-shell.
- Remove the aside "ai-chat" tab handling and delete ai-chat-panel.tsx.
- Type IAiChatMessageRow.metadata.usage; add "Minimize" and
  "Tokens used in this chat" i18n keys.
2026-06-17 17:11:01 +03:00
vvzvlad 44b340dc1a feat(ai-chat): agent write tools, provenance wiring, chat panel + provider settings UI" -m "Backend:
- Add reversible write tools to the per-user agent toolset (page create/update/
  move/soft-delete; comment reply + resolve), exposed under the user's JWT and
  enforced by Docmost CASL; no permanent/force delete (D3).
- Non-spoofable agent provenance: sign actor/aiChatId into the access and collab
  tokens (TokenService), propagate via jwt.strategy onto the request, and set
  pages.last_updated_source/last_updated_ai_chat_id on REST create/update/move and
  comments.created_source/resolved_source/ai_chat_id.
- packages/mcp: add an optional getCollabToken provider (content-edit provenance)
  and guard against empty tokens; service-account /mcp path unchanged.

Frontend:
- Admin 'AI / Models' settings section: provider/model/embedding/base URL, a
  write-only API key field, system prompt, and Test connection.
- AI chat panel (useChat + DefaultChatTransport): conversation list, streamed
  messages, tool-call action log and page citations; header entry point gated on
  settings.ai.chat.

Compile-verified (server nest build + client tsc/vite); not yet live-tested.
Known gaps: history 'AI agent' badge (C3), vector RAG (D), external MCP (E);
chat tool-card citation links pending a fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-17 02:39:26 +03:00
vvzvlad 0e069ddba0 style(page-tree): shrink default tree indentation 16px -> 8px
Port the compact page-tree indentation tweak from the docmost-app
WebKit wrapper (previously applied via injected CSS) into the source.

- doc-tree.tsx: change the default `indentPerLevel` prop from 16 to 8,
  giving an 8px step per nesting level for a more compact page tree.

No callers override the value, so the single default change applies
everywhere DocTree is rendered. EE-hiding injections from docmost-app
were skipped: those surfaces are already removed in this community fork.
2026-06-16 23:06:32 +03:00
vvzvlad a88b3f776c feat(fork)!: remove all frontend Enterprise-Edition code (community build)
Strip the proprietary client EE so the fork ships a clean community/AGPL
edition, mirroring Forkmost. Delete apps/client/src/ee (201 files) and
packages/ee, and patch every consumer that imported from @/ee/*.

- gate-out EE features (useHasFeature -> false): API keys, SSO, MFA, SCIM,
  audit logs, AI / AI-chat, templates, page permissions, page verification,
  comment resolution, trash retention, viewer comments
- drop cloud/billing/trial/entitlement/posthog flows; sign-in is now
  email+password only (no SSO/LDAP/cloud)
- remove EE routes from App.tsx and EE entries from sidebars/settings nav
- restore the community page-share button (ShareModal) that the EE
  PageShareModal used to provide
- remove the dead "Attachments" search filter, dead MFA navigation and
  orphaned route constants

Client type-checks clean; full `pnpm build` is green for all three projects.
2026-06-16 22:32:44 +03:00
Philip Okugbe 6191acfa14 fix: a11y (#2275) 2026-06-09 22:51:55 +01:00
Philip Okugbe 92c0e36e46 fix(a11y): WCAG 2.1 AA fixes (#2219) 2026-05-20 16:47:25 +01:00
Peter Tripp 932c1ad5b7 Better trash (#2190)
* Better trash

I recently lost a bunch of time editing and searching for pages that were actually in the Trash. Docmost intentionally tries to not link to Trashed pages, but the url of that Trashed page and any inbound links still work.  This makes it clearer when a page you are interacting with is in the Trash.

- /trash
  - Refactored banner into `trash-banner.tsx`
  - Refactored "Restore" modal into `use-restore-page-modal.tsx`
- Page (when isDeleted)
  - Add: `trash-banner.tsx`
  - Add breadcrumbs: `Parent / Child / Page (Deleted)`
  - Change: Deleted Pages are read-only
  - Replace "Move to Trash" with "Restore" in page menu (invokes `use-restore-page-modal`)

I tried very hard to keep this simple and re-use existing translation strings wherever possible.

* cleanup

---------

Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
2026-05-14 14:41:10 +01:00
Julien Fontanet 82d065669d fix: page mode toggle no longer overwrites default preference (#1996)
The header edit/read toggle now controls only the current session's mode
without saving it as the user's preference. The saved preference (set in
profile settings) is applied once on initial load and sticks across page
navigations within the session, so navigating to a new page no longer
resets the mode mid-session.

Fixes #1693
2026-05-14 13:15:03 +01:00
Philip Okugbe cea9be7926 feat: table enhancement (#2191) 2026-05-14 00:37:44 +01:00
Philip Okugbe 31ed0df3f7 feat(tree): replace sidebar tree (react-aborist) with custom tree implementation (#2199)
* feat(tree): replace react-arborist with custom tree implementation

* feat(tree): keyboard arrow navigation between rows

* feat(emoji-picker): focus search input on open

* refactor(emoji): switch to @slidoapp/emoji-mart fork for accessibility

* feat(tree): Home/End and typeahead keyboard navigation

* feat(tree): roving tabindex and * to expand sibling subtrees

* feat(tree): Space activation and ARIA refinements

* fix(tree): move treeitem role to focusable row + aria-current
2026-05-13 23:01:04 +01:00
Philip Okugbe dbe6c2d6ba feat: A11y fixes (#2148) 2026-05-04 21:21:37 +01:00
Philip Okugbe c247d4c1e3 feat(ee): PDF import (#2142)
* feat: replace pdfjs-dist with firecrawl-pdf-inspector

* use modified firecrawl-pdf-inspector

* feat: pdf import

* increase single file upload size limit

* use npm package

* sync

* update package
2026-05-01 14:56:39 +01:00
Philip Okugbe cc00e77dfb fix: space overview favorites (#2110) 2026-04-14 02:58:24 +01:00
Philip Okugbe bd68e47e03 feat(ee): page verification workflow (#2102)
* feat: page verification workflow

* feat: refactor page-verification

* sync

* fix type

* fix

* fix

* notification icon

* use full word

* accept .license file

* - update templates
- update migration and notification

* fix copy

* update audit labels

* sync

* add space name
2026-04-13 20:20:34 +01:00
Philip Okugbe d42091ccb1 feat: favorites (#2103)
* feat: favorites and templates(ee)

* rename migrations

* fix sidebar

* cleanup tabs

* fix

* turn off templates

* cleanup

* uuid validation
2026-04-12 22:06:25 +01:00
Philip Okugbe 879aa2c3d8 feat: page update notifications (#2074)
* feat: watchers notification and email preferences

* fix: email copy

* digests

* clean up

* fix

* clean up

* move backlinks queue-up to history processor

* fix

* fix keys

* feat: group notifications

* filter

* adjust email digest window
2026-03-31 16:03:59 +01:00
Philip Okugbe fa4872e89e fix(deps): package updates (#2041)
* update
* overrides
* override
* fix page update mutation
* fix
* cleanup
* loader
* fix excalidraw package
* override
* fix regex
2026-03-25 10:07:01 +00:00
Philip Okugbe d7a5fda53c feat: better feature flags (#2026)
* feat: feature flag upgrade

* fix translations

* refactor

* fix

* fix
2026-03-15 22:05:32 +00:00
Philipinho 057360c6be fix: validate import size 2026-03-03 20:00:05 +00:00
Philip Okugbe 69d7532c6c feat(ee): audit logs (#1977)
feat: clickhouse driver
* sync
* updates
2026-03-01 01:29:03 +00:00
Philip Okugbe fc0997fd90 feat: editor attachment paste handling (#1975)
* reupload attachments if uploaded to a different page
* use image dimensions on paste/DnD

* tooltips withinPortal:false

* isolating attribute
2026-02-28 01:24:19 +00:00
Philip Okugbe 59e945562d feat(ee): page-level access/permissions (#1971)
* Add page_hierarchy table

* feat(ee): page-level permissions

* pagination

* rename migration
fixes

* fix

* tabs

* fix theme

* cleanup

* sync

* page permissions notification
* other fixes

* sharing disbled

* fix column nodes

* toggle error handling
2026-02-26 19:49:10 +00:00
Philipinho 2ebdc2baea empty states 2026-02-16 00:33:16 +00:00
Philip Okugbe 05b3c65b0f feat: notifications (#1947)
* feat: notifications
* feat: watchers

* improvements

* handle page move for watchers

* make watchers non-blocking

* more
2026-02-14 20:00:38 -08:00
Philipinho 55280db672 dark color theme tweaks 2026-02-14 10:35:03 -08:00
Philip Okugbe 7879e1f600 fix: add execCommand fallback for clipboard (#1927)
* fix: add execCommand fallback for clipboard
2026-02-09 14:44:27 -08:00
Philip Okugbe 2f97a3debc feat: DOCX import (#1913) 2026-02-06 10:34:51 -08:00
Philip Okugbe 78b1c1a453 feat: switch to cursor pagination (#1884)
* add cursor pagination function

* support custom order modifier
* refactor returned object

* feat(db): migrate paginated endpoints to cursor-based pagination

* sync

* support hasPrevPage boolean

* feat(client): migrate pagination from offset to cursor-based

* support beforeCursor/prevCursor

* wrap search results in items array for API consistency
2026-01-30 19:28:54 +00:00
Philip Okugbe 6ccb2bb872 feat(export): add metadata file to preserve page icons and ordering on import (#1877)
* feat(export): add metadata file to preserve page icons and ordering on import
- Export includes `docmost-metadata.json`
- Import reads metadata to restore icons and sort siblings by original position

* cleanup

* bonus fixes

* handle unknown prosemirror nodes

* add docmost app  version
2026-01-27 16:39:39 +00:00
Philip Okugbe 351b075ebb fix(tree): update sidebar-pages cache directly instead of refetching on page move (#1870) 2026-01-25 12:38:44 +00:00
Philip Okugbe 54775f537d fix: handle malformed URLs gracefully during import/export (#1868)
* Handling malformed URLs gracefully

* Allow import of invalid URLs, but adding logging.

---------

Co-authored-by: gpapp <gergely.papp@itworks.hu>
2026-01-25 00:48:43 +00:00
Philip Okugbe aa6a046aa6 feat(export): add export loading state and copy as markdown (#1867)
* feat: add loading state to export

* feat: copy as markdown

* preserve taskList comment
2026-01-24 23:30:17 +00:00
Philip Okugbe 657fdf8cb7 feat: Tiptap V3 migration (#1854)
* Tiptap3 migration - WIP

* fix collaboration

* remove unused code

* fix flicker

* disable duplicate extensions

* update tiptap version

* Switch to useEditorState
- Set shouldRerenderOnTransaction to false

* fix editable state

* add tippyoptions for reference

* merge main

* tiptap 3.6.1

* fix bubble menu

* fix converter

* fix menus

* fix collaboration caret css

* fix: Set `isInitialized` to force immediate react node view rendering

* feat: Migrate tippy.js menus to Floating UI

* feat: Update collaboration connection for HocusPocus v3

* fix: Connect/disconnect websocketProvider

* cleanup

* cleanup

* feat: Improved placeholder and upload handling for images

* feat: Improved placeholder and upload handling for videos

* refactor: Image node and view clean-up

* feat: Improved placeholder and upload handling for attachments

* fix: Video view styles

* fix: Transaction handling on asset upload

* fix: Use imageDimensionsFromStream

* feat: Multiple file upload, improved placeholders, local previews

* fix: Drag & drop, paste upload

* fix: Allow media as attachment

* * add skeleton pulse animation
* add translation strings
* fix attachment view responsiveness

* fix collab connection status display

* Tiptap v3.17.0

* fix suggestion menu exit bug

* fix search shortcut

* fix history editor css

* tiptap 3.17.1

---------

Co-authored-by: Arek Nawo <areknawo@areknawo.com>
2026-01-24 20:41:08 +00:00
Philip Okugbe 0bbc1c35de fix: public sharing performance improvements (#1841) 2026-01-13 16:00:22 +00:00
Philip Okugbe d2629afff2 feat: anchor links (#1765)
* feat: add heading extension with unique ID support and scroll functionality
* Added unique id for heading
* remove baseUrl heading storage
* move heading to extensions package
* WIP
* support anchors in mentions
* enhance scrolling functionality
* nodeId function
* fix nanoid import
* Bring unique-id extension local
* fixes
* fix internal link scroll in public pages
* add unique id server side
* rename mention anchor to anchorId
* capture first anchorId on paste

---------

Co-authored-by: Romik <40670677+RomikMakavana@users.noreply.github.com>
2025-12-06 14:46:54 +00:00
Philip Okugbe 1280f96f37 feat: implement space and workspace icons (#1558)
* feat: implement space and workspace icons
- Create reusable AvatarUploader component supporting avatars, space icons, and workspace icons
- Add Sharp package for server-side image resizing and optimization
- Create reusable AvatarUploader component supporting avatars, space icons, and workspace icons
- Support removing icons

* add workspace logo support
- add upload loader
- add white background to transparent image
- other fixes and enhancements

* dark mode

* fixes

* cleanup
2025-09-15 21:11:37 +01:00
Philipinho 61d1cf88a7 fix: reset file inputs after import 2025-09-15 12:52:31 +01:00