Skip to content
Merged
Show file tree
Hide file tree
Changes from 42 commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
c82fac7
feat: Add object-level tags, note editing, and auto-create task calendar
rubenvdlinde Mar 25, 2026
4cc9b76
fix: Audit trail filtering by object UUID instead of numeric ID
rubenvdlinde Mar 25, 2026
ce0c026
fix(openregister): add missing migrations, routes, and DI for spec br…
rubenvdlinde Mar 25, 2026
a1f6a75
fix: Support bracket notation for sort params in audit trail API
rubenvdlinde Mar 25, 2026
f81a5a9
fix(openregister): resolve merge conflicts between mail-sidebar, cont…
rubenvdlinde Mar 25, 2026
3b340a2
Merge remote-tracking branch 'origin/development' into feature/1003/n…
rubenvdlinde Mar 25, 2026
14f6d14
chore: fix .gitignore and remove docs/node_modules from tracking
rubenvdlinde Mar 25, 2026
0ec1410
fix: resolve all PHPCS and ESLint quality errors
rubenvdlinde Mar 25, 2026
b9b91f9
fix: remove vue-richtext dep conflict, suppress eslint import
rubenvdlinde Mar 25, 2026
b5f62de
fix: restore package.json and package-lock.json from development
rubenvdlinde Mar 25, 2026
aae722b
merge: resolve package.json conflict from sidebar-backend-apis
rubenvdlinde Mar 26, 2026
680e987
feat: Add unified Nextcloud entity linking system (linked-entity-types)
rubenvdlinde Mar 26, 2026
eae016f
fix: Wire LinkedEntityEnricher into RenderObject pipeline
rubenvdlinde Mar 26, 2026
0b715b3
docs: Sync linked-entity-types delta specs to main specs
rubenvdlinde Mar 26, 2026
493d5b4
merge: Incorporate full spec branch from feature/1003/nextcloud-entit…
rubenvdlinde Mar 26, 2026
9d7dc78
refactor: Migrate EmailService, ContactService, DeckCardService to _ …
rubenvdlinde Mar 26, 2026
ae456b0
docs: Archive linked-entity-types and refactor-link-services changes
rubenvdlinde Mar 26, 2026
f074e81
fix: Update controllers to match refactored service signatures
rubenvdlinde Mar 26, 2026
03272ee
fix: Register MailAppScriptListener and fix event binding
rubenvdlinde Mar 26, 2026
336f78c
fix: Allow slashes in entityId route params and register listener
rubenvdlinde Mar 26, 2026
4a724d8
fix: Add linked type columns to ObjectEntity serialization and fix se…
rubenvdlinde Mar 26, 2026
b6cf1cc
fix: MagicMapper persistence for linked entity columns
rubenvdlinde Mar 26, 2026
1459c79
fix: Mail sidebar frontend fixes — webpack entry, path routing, logging
rubenvdlinde Mar 26, 2026
d448cd3
fix: Mount sidebar as sibling of app-content-vue, not child
rubenvdlinde Mar 26, 2026
61fc963
fix: Add try-catch and detailed logging to sidebar Vue mount
rubenvdlinde Mar 26, 2026
04948cc
fix: Mount mail sidebar to document.body to survive Vue re-renders
rubenvdlinde Mar 26, 2026
d014589
feat: Redesign mail sidebar with 3 tabs — Actions, Objects, Entities
rubenvdlinde Mar 26, 2026
2d395f3
feat: Use NcAppSidebar + NcAppSidebarTab for mail sidebar tabs
rubenvdlinde Mar 26, 2026
3cd3e24
fix: Pre-load first 20 objects per schema in Actions tab
rubenvdlinde Mar 26, 2026
6b98c4b
fix: Show object name instead of UUID in Actions tab dropdown
rubenvdlinde Mar 26, 2026
d8acb45
fix: Avoid URL-encoding slash in mail ref for reverse lookup and unlink
rubenvdlinde Mar 27, 2026
58def45
fix: Remove tests/integration/node_modules from repo
rubenvdlinde Apr 8, 2026
c76e643
merge: resolve conflicts with development
rubenvdlinde Apr 10, 2026
b0df3ae
merge: resolve conflicts with development
rubenvdlinde Apr 10, 2026
5c79d06
merge: resolve conflicts with development
rubenvdlinde Apr 10, 2026
e97eb24
fix: resolve leftover conflict markers in Organisation.php and spec
rubenvdlinde Apr 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

/node_modules/
/website/node_modules/
/docs/node_modules/
/website/.docusaurus/
/js/
/custom_apps/
Expand Down
3 changes: 2 additions & 1 deletion .license-overrides.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"@fortawesome/free-solid-svg-icons": "License is (CC-BY-4.0 AND MIT) — both are approved open-source licenses, compound AND expression not parsed by checker",
"smalot/pdfparser": "License is LGPL-3.0 — equivalent to LGPL-3.0-only which is on the allowlist, SPDX identifier variation not recognized by checker"
"smalot/pdfparser": "License is LGPL-3.0 — equivalent to LGPL-3.0-only which is on the allowlist, SPDX identifier variation not recognized by checker",
"apexcharts": "License is MIT — license-checker misreads logo URL as custom license, see https://github.com/apexcharts/apexcharts.js/blob/main/LICENSE"
}
41 changes: 34 additions & 7 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,39 @@
['name' => 'endpoints#patch', 'url' => '/api/endpoints/{id}', 'verb' => 'PATCH', 'requirements' => ['id' => '[^/]+']],
['name' => 'mappings#patch', 'url' => '/api/mappings/{id}', 'verb' => 'PATCH', 'requirements' => ['id' => '[^/]+']],
['name' => 'consumers#patch', 'url' => '/api/consumers/{id}', 'verb' => 'PATCH', 'requirements' => ['id' => '[^/]+']],
['name' => 'actions#patch', 'url' => '/api/actions/{id}', 'verb' => 'PATCH', 'requirements' => ['id' => '[^/]+']],

// Actions - Custom routes.
['name' => 'actions#test', 'url' => '/api/actions/{id}/test', 'verb' => 'POST', 'requirements' => ['id' => '\d+']],
['name' => 'actions#logs', 'url' => '/api/actions/{id}/logs', 'verb' => 'GET', 'requirements' => ['id' => '\d+']],
['name' => 'actions#migrateFromHooks', 'url' => '/api/actions/migrate-from-hooks/{schemaId}', 'verb' => 'POST', 'requirements' => ['schemaId' => '\d+']],

// Contacts - matching.
['name' => 'contacts#match', 'url' => '/api/contacts/match', 'verb' => 'GET'],

// Archival and destruction workflow.
['name' => 'archival#listSelectionLists', 'url' => '/api/archival/selection-lists', 'verb' => 'GET'],
['name' => 'archival#createSelectionList', 'url' => '/api/archival/selection-lists', 'verb' => 'POST'],
['name' => 'archival#getSelectionList', 'url' => '/api/archival/selection-lists/{id}', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#updateSelectionList', 'url' => '/api/archival/selection-lists/{id}', 'verb' => 'PUT', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#deleteSelectionList', 'url' => '/api/archival/selection-lists/{id}', 'verb' => 'DELETE', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#getRetention', 'url' => '/api/archival/objects/{id}/retention', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#setRetention', 'url' => '/api/archival/objects/{id}/retention', 'verb' => 'PUT', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#listDestructionLists', 'url' => '/api/archival/destruction-lists', 'verb' => 'GET'],
['name' => 'archival#generateDestructionList', 'url' => '/api/archival/destruction-lists/generate', 'verb' => 'POST'],
['name' => 'archival#getDestructionList', 'url' => '/api/archival/destruction-lists/{id}', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#approveDestructionList', 'url' => '/api/archival/destruction-lists/{id}/approve', 'verb' => 'POST', 'requirements' => ['id' => '[^/]+']],
['name' => 'archival#rejectFromDestructionList', 'url' => '/api/archival/destruction-lists/{id}/reject', 'verb' => 'POST', 'requirements' => ['id' => '[^/]+']],

// Linked entities — generic API for ad-hoc linking and reverse lookups.
['name' => 'linked_entity#addObjectLink', 'url' => '/api/objects/{uuid}/_linked/{type}', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+', 'type' => '[a-z]+']],
['name' => 'linked_entity#removeObjectLink', 'url' => '/api/objects/{uuid}/_linked/{type}/{entityId}', 'verb' => 'DELETE', 'requirements' => ['uuid' => '[^/]+', 'type' => '[a-z]+', 'entityId' => '.+']],
['name' => 'linked_entity#addRegisterLink', 'url' => '/api/registers/{uuid}/_linked/{type}', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+', 'type' => '[a-z]+']],
['name' => 'linked_entity#addSchemaLink', 'url' => '/api/schemas/{uuid}/_linked/{type}', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+', 'type' => '[a-z]+']],
['name' => 'linked_entity#reverseLookup', 'url' => '/api/linked/{type}/{entityId}', 'verb' => 'GET', 'requirements' => ['type' => '[a-z]+', 'entityId' => '.+']],

// Email links (mail sidebar).
['name' => 'emails#byMessage', 'url' => '/api/emails/by-message/{accountId}/{messageId}', 'verb' => 'GET', 'requirements' => ['accountId' => '\d+', 'messageId' => '\d+']],
// Email links — sender-based lookup (uses Mail app DB directly).
['name' => 'emails#bySender', 'url' => '/api/emails/by-sender', 'verb' => 'GET'],
['name' => 'emails#quickLink', 'url' => '/api/emails/quick-link', 'verb' => 'POST'],
['name' => 'emails#deleteLink', 'url' => '/api/emails/{linkId}', 'verb' => 'DELETE', 'requirements' => ['linkId' => '\d+']],

// Workflow executions.
['name' => 'workflowExecution#index', 'url' => '/api/workflow-executions', 'verb' => 'GET'],
Expand Down Expand Up @@ -324,14 +351,14 @@
// Contact relations (CardDAV wrapper).
['name' => 'contacts#index', 'url' => '/api/objects/{register}/{schema}/{id}/contacts', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'contacts#create', 'url' => '/api/objects/{register}/{schema}/{id}/contacts', 'verb' => 'POST', 'requirements' => ['id' => '[^/]+']],
['name' => 'contacts#update', 'url' => '/api/objects/{register}/{schema}/{id}/contacts/{contactId}', 'verb' => 'PUT', 'requirements' => ['id' => '[^/]+', 'contactId' => '\d+']],
['name' => 'contacts#destroy', 'url' => '/api/objects/{register}/{schema}/{id}/contacts/{contactId}', 'verb' => 'DELETE', 'requirements' => ['id' => '[^/]+', 'contactId' => '\d+']],
['name' => 'contacts#update', 'url' => '/api/objects/{register}/{schema}/{id}/contacts/{contactUid}', 'verb' => 'PUT', 'requirements' => ['id' => '[^/]+', 'contactUid' => '[^/]+']],
['name' => 'contacts#destroy', 'url' => '/api/objects/{register}/{schema}/{id}/contacts/{contactUid}', 'verb' => 'DELETE', 'requirements' => ['id' => '[^/]+', 'contactUid' => '[^/]+']],
['name' => 'contacts#objects', 'url' => '/api/contacts/{contactUid}/objects', 'verb' => 'GET'],

// Deck card relations (Nextcloud Deck wrapper).
['name' => 'deck#index', 'url' => '/api/objects/{register}/{schema}/{id}/deck', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'deck#create', 'url' => '/api/objects/{register}/{schema}/{id}/deck', 'verb' => 'POST', 'requirements' => ['id' => '[^/]+']],
['name' => 'deck#destroy', 'url' => '/api/objects/{register}/{schema}/{id}/deck/{deckId}', 'verb' => 'DELETE', 'requirements' => ['id' => '[^/]+', 'deckId' => '\d+']],
['name' => 'deck#destroy', 'url' => '/api/objects/{register}/{schema}/{id}/deck/{deckRef}', 'verb' => 'DELETE', 'requirements' => ['id' => '[^/]+', 'deckRef' => '[^/]+']],
['name' => 'deck#objects', 'url' => '/api/deck/boards/{boardId}/objects', 'verb' => 'GET', 'requirements' => ['boardId' => '\d+']],

// Unified entity relations.
Expand Down
200 changes: 200 additions & 0 deletions css/mail-sidebar.css
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,10 @@
.or-mail-sidebar__content {
flex: 1;
overflow-y: auto;
overflow-x: hidden;
padding: 12px;
display: flex;
flex-direction: column;
}

/* Header */
Expand Down Expand Up @@ -431,3 +434,200 @@
max-width: 320px;
}
}

/* Tabs are handled by NcAppSidebar/NcAppSidebarTab components */

/* ========================================
Tab: Common
======================================== */
.or-tab-empty {
color: var(--color-text-maxcontrast);
font-size: 13px;
padding: 16px 0;
text-align: center;
}

.or-tab-loading {
color: var(--color-text-maxcontrast);
font-size: 13px;
padding: 16px 0;
text-align: center;
}

/* ========================================
Tab: Actions
======================================== */
.or-action-block {
margin-bottom: 16px;
}

.or-action-label {
display: block;
font-size: 13px;
font-weight: 600;
color: var(--color-main-text);
margin-bottom: 4px;
}

.or-action-search {
position: relative;
}

.or-action-input {
width: 100%;
padding: 8px 10px;
border: 1px solid var(--color-border);
border-radius: var(--border-radius-large, 6px);
background: var(--color-main-background);
color: var(--color-main-text);
font-size: 13px;
box-sizing: border-box;
height: 36px;
}

.or-action-input:focus {
border-color: var(--color-primary);
outline: none;
}

.or-action-results {
position: absolute;
top: 100%;
left: 0;
right: 0;
background: var(--color-main-background);
border: 1px solid var(--color-border);
border-top: none;
border-radius: 0 0 var(--border-radius, 3px) var(--border-radius, 3px);
max-height: 200px;
overflow-y: auto;
z-index: 10;
list-style: none;
margin: 0;
padding: 0;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
}

.or-action-result {
padding: 8px 10px;
cursor: pointer;
font-size: 13px;
}

.or-action-result:hover {
background: var(--color-background-hover);
}

.or-action-result-name {
color: var(--color-main-text);
}

.or-action-searching {
font-size: 12px;
color: var(--color-text-maxcontrast);
padding: 4px 0;
}

/* ========================================
Tab: Objects
======================================== */
.or-objects-list {
list-style: none;
margin: 0;
padding: 0;
}

.or-object-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 8px 0;
border-bottom: 1px solid var(--color-border-dark, var(--color-border));
}

.or-object-item:last-child {
border-bottom: none;
}

.or-object-info {
flex: 1;
min-width: 0;
}

.or-object-name {
display: block;
font-size: 13px;
font-weight: 600;
color: var(--color-main-text);
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}

.or-object-schema {
display: block;
font-size: 11px;
color: var(--color-text-maxcontrast);
}

.or-object-unlink {
background: none;
border: none;
color: var(--color-text-maxcontrast);
cursor: pointer;
font-size: 14px;
padding: 4px 6px;
border-radius: var(--border-radius, 3px);
flex-shrink: 0;
}

.or-object-unlink:hover {
color: var(--color-error);
background: var(--color-background-hover);
}

/* ========================================
Tab: Entities
======================================== */
.or-entity-group {
margin-bottom: 12px;
}

.or-entity-group-title {
font-size: 12px;
font-weight: 600;
color: var(--color-text-maxcontrast);
text-transform: uppercase;
letter-spacing: 0.5px;
margin: 0 0 4px;
}

.or-entity-list {
list-style: none;
margin: 0;
padding: 0;
}

.or-entity-item {
display: flex;
justify-content: space-between;
align-items: center;
padding: 4px 0;
font-size: 13px;
}

.or-entity-value {
color: var(--color-main-text);
flex: 1;
min-width: 0;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}

.or-entity-confidence {
font-size: 11px;
color: var(--color-text-maxcontrast);
flex-shrink: 0;
margin-left: 8px;
}
15 changes: 12 additions & 3 deletions docusaurus/docusaurus.config.js → docs/docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ const config = {
// metadata like html lang
i18n: {
defaultLocale: 'en',
locales: ['en'],
locales: ['en', 'nl'],
localeConfigs: {
en: { label: 'English' },
nl: { label: 'Nederlands' },
},
},

presets: [
Expand All @@ -29,10 +33,11 @@ const config = {
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
path: '../docs',
path: './',
exclude: ['**/node_modules/**'],
sidebarPath: require.resolve('./sidebars.js'),
editUrl:
'https://github.com/conductionnl/openregister/tree/main/docusaurus/',
'https://github.com/conductionnl/openregister/tree/main/docs/',
},
blog: false,
theme: {
Expand Down Expand Up @@ -94,6 +99,10 @@ const config = {
label: 'GitHub',
position: 'right',
},
{
type: 'localeDropdown',
position: 'right',
},
],
},
footer: {
Expand Down
Loading
Loading