Add overflow-hidden to card container, min-w-0 to flex row, and
truncate to path text div so long NAS paths don't push badges
and copy icon outside the visible area.
Browsers block file:/// URLs from web pages for security. Changed:
- Detail sheet: click on NAS attachment copies path to clipboard with
'Copiat!' green badge feedback. Full UNC path shown below.
- Entry form: NAS link click = copy path (removed window.open fallback)
- Removed unused toFileUrl/toFileUrlByIp imports from form
- User pastes in Explorer address bar to open the file
- New nas-paths.ts config: drive mappings, UNC normalization, file:/// URL builder
- RegistryAttachment type extended with optional networkPath field
- 'Link NAS' button in attachment section opens inline path input
- Network path entries shown with blue HardDrive icon + NAS badge
- Click opens in Explorer via file:/// URL, copy path button on hover
- P:\ auto-converted to \\newamun\Proiecte UNC path
- Short display path shows share + last 2 segments
- Validation: warns if path doesn't match known NAS mappings
Replace placeholder WiFi string display with actual QR code rendered
on canvas via 'qrcode' library. Dialog now shows scannable QR image
with copy-image and download-PNG buttons.
Registratura improvements:
- Thread Explorer: new 'Fire conversatie' tab with timeline view, search, stats, gap tracking (la noi/la institutie), export to text report
- Interactive I/O toggle: replaced direction dropdown with visual blue/orange button group (Intrat/Iesit with icons)
- Doc type UX: alphabetical sort + immediate selection after adding custom type
- AC Validity Tracker: full Autorizatie de Construire lifecycle workflow (12mo validity, execution phases, extension request, required docs checklist, monthly reminders, abandonment/expiry tracking)
Password Vault rework (renamed to 'Parole Uzuale' v0.3.0):
- New categories: WiFi, Portale Primarii, Avize Online, PIN Semnatura, Software, Hardware (replaced server/database/api)
- Category icons (lucide-react) throughout list and form
- WiFi QR code dialog with connection string copy
- Context-aware form (PIN vs password label, hide email for WiFi/PIN, hide URL for WiFi, hide generator for PIN)
- Dynamic stat cards showing top 3 categories by count
- Removed encryption banner
- Updated i18n, flags, config
- ManicTime parser service: parse/serialize Tags.txt format, classify lines into project/phase/activity
- API route /api/manictime: GET (read + sync plan), POST (pull/push/both with backup versioning)
- ManicTimeSyncPanel component: connection check, stats grid, import/export/full sync with confirmation dialog
- Integrated into Tag Manager module with live sync status
- Docker: MANICTIME_TAGS_PATH env var, SMB volume mount /mnt/manictime
- Hierarchy validation: project codes, company association, duplicate detection
- Version bump to 0.2.0
- Created src/core/crypto/ with AES-256-GCM encrypt/decrypt (PBKDF2 key derivation)
- Created /api/vault route: CRUD with server-side password encryption
- PATCH /api/vault migration endpoint to re-encrypt legacy plaintext passwords
- Rewrote use-vault hook to use dedicated /api/vault instead of generic storage
- Updated UI: amber 'not encrypted' warning green 'encrypted' badge
- Added ENCRYPTION_SECRET env var to docker-compose.yml and stack.env
- Module version bumped to 0.2.0
- Renamed from 'Sabloane Word' to 'Biblioteca Sabloane' (Template Library)
- Multi-format support: Word, Excel, PDF, DWG, Archicad with auto-detection
- Auto versioning: 'Revizie Noua' button archives current version, bumps semver
- Version history dialog: browse and download any previous version
- Simplified UX: file upload vs external link toggle, auto-detect placeholders
silently for .docx, hide placeholders section for non-Word formats
- File type icons: distinct icons for docx, xlsx, archicad, dwg, pdf
- Updated stats cards: Word/Excel count, DWG/Archicad count, versioned count
- Backward compatible: old entries without fileType/versionHistory get defaults
- AD prefill: 'Din cont' button pre-fills name + company from Authentik session
- Logo size slider: 50%-200% scale control in Stil & Aranjare section
- Promotional banner: configurable image+link below signature with preview
- US/SDT custom graphics: dedicated dash (US) and dot (SDT) decorative icons
replacing Beletage's grey/accent slashes for company-specific branding
- Remove 'initials' type, expirationDate, legalStatus, usageNotes fields
- Add subcategory field with creatable input + 6 default categories
- Add TIFF upload support with client-side utif2 decode for preview
- Store original TIFF data separately for faithful downloads
- Add download dropdown: Original file, Word (.docx), PDF (.pdf)
- Group assets by subcategory in list view
- Add subcategory filter in search bar
- Install docx, jspdf, utif2 packages
- Closes 3.07
The client-side migration was downloading 25-50MB of base64 data to the
browser before showing anything. getAllEntries also lost its lightweight flag.
Fix:
- New POST /api/storage/migrate-blobs endpoint runs entirely server-side
(loads entries one-at-a-time from PostgreSQL, never sends heavy data to browser)
- Restore lightweight:true on getAllEntries (strips remaining base64 in API)
- Migration fires on mount (fire-and-forget) while list loads independently
- Remove client-side migrateEntryBlobs function
Replace complex prisma.\ with simple Prisma findMany + JS stripping.
Now that entries are inherently small (base64 in separate blob namespace),
JS-based stripping is instant. Also fix migration to check flag before loading.
Root cause: even with SQL-level stripping, PostgreSQL must TOAST-decompress
entire multi-MB JSONB values from disk before any processing. For 5 entries
with PDF attachments (25-50MB total), this takes several seconds.
Fix: store base64 attachment data in separate namespace 'registratura-blobs'.
Main entries are inherently small (~1-2KB). List queries never touch heavy data.
Changes:
- registry-service.ts: extractBlobs/mergeBlobs split base64 on save/load,
migrateEntryBlobs() one-time migration for existing entries
- use-registry.ts: dual namespace (registratura + registratura-blobs),
migration runs on first mount
- registratura-module.tsx: removed useContacts/useTags hooks that triggered
2 unnecessary API fetches on page load (write-only ops use direct storage)
Before: 3 API calls on mount, one reading 25-50MB from PostgreSQL
After: 1 API call on mount, reading ~5-10KB total
Previous fix stripped data in Node.js AFTER Prisma loaded the full JSON
from PostgreSQL. For 5 entries with PDF attachments, this still meant
25-50MB transferring from DB to Node.js on every page load.
Now uses prisma.\ with nested jsonb_each/jsonb_object_agg to
strip data/fileData/imageUrl strings >1KB inside the database itself.
Heavy base64 never leaves PostgreSQL when lightweight=true.
ROOT CAUSE: RegistryEntry stores file attachments as base64 strings in JSON.
A single 5MB PDF becomes ~6.7MB of base64. With 6 entries, the exportAll()
endpoint was sending 30-60MB of JSON on every page load taking 2+ minutes.
Fix: Added ?lightweight=true parameter to /api/storage GET endpoint.
When enabled, stripHeavyFields() recursively removes large 'data' and
'fileData' string fields (>1KB) from JSON values, replacing with '__stripped__'.
Changes:
- /api/storage route.ts: stripHeavyFields() + lightweight query param
- StorageService.export(): accepts { lightweight?: boolean } option
- DatabaseStorageAdapter.export(): passes lightweight flag to API
- LocalStorageAdapter.export(): accepts option (no-op, localStorage is fast)
- useStorage.exportAll(): passes options through
- registry-service.ts: getAllEntries() uses lightweight=true by default
- registry-service.ts: new getFullEntry() loads single entry with full data
- use-registry.ts: exports loadFullEntry() for on-demand full loading
- registratura-module.tsx: handleEdit/handleNavigateEntry load full entry
Result: List loading transfers ~100KB instead of 30-60MB. Editing loads
full data for a single entry on demand (~5-10MB for one entry vs all).
CRITICAL PERF BUG: Every hook did storage.list() (1 HTTP call fetching ALL
items with values, discarding values, returning only keys) then storage.get()
for EACH key (N individual HTTP calls re-fetching values one by one).
With 6 entries + contacts + tags, Registratura page fired ~40 sequential
HTTP requests on load, where 3 would suffice.
Fix: Replace list()+N*get() with single exportAll() call in ALL hooks:
- registratura/registry-service.ts (added exportAll to RegistryStorage interface)
- address-book/use-contacts.ts
- it-inventory/use-inventory.ts
- password-vault/use-vault.ts
- word-templates/use-templates.ts
- prompt-generator/use-prompt-generator.ts
- hot-desk/use-reservations.ts
- email-signature/use-saved-signatures.ts
- digital-signatures/use-signatures.ts
- ai-chat/use-chat.ts
- core/tagging/tag-service.ts (uses storage.export())
Additional fixes:
- registratura/use-registry.ts: addEntry uses optimistic local state update
instead of double-refresh; closeEntry batches saves with Promise.all +
single refresh
- server-rack.tsx: reversed slot rendering so U1 is at bottom (standard
rack numbering, per user's physical rack)
Performance impact: ~90% reduction in HTTP requests on page load for all modules
- Added ClosureInfo type with reason, closedBy, closedAt, linkedEntry, hadActiveDeadlines, attachment
- Rewrote close-guard-dialog into universal close dialog (always shown on close)
- Reason field (always required)
- Optional continuation entry search+link
- Optional closing document attachment (file upload)
- Active deadlines shown as warning banner when present
- Created ClosureBanner component (read-only, shown at top of closed entry edit)
- Shows who, when, why, linked entry (clickable), attached doc (downloadable)
- All closes now go through the dialog no more silent closeEntry
- Linked-entries sub-dialog preserved as second step
- Dynamic document types: string-based DocumentType synced with Tag Manager
(new types auto-create tags under 'document-type' category)
- Added default types: 'Apel telefonic', 'Videoconferinta'
- Bidirectional Address Book: quick-create contacts from sender/recipient/
assignee fields via QuickContactDialog popup
- Simplified status: Switch toggle replaces dropdown (default open)
- Responsabil (Assignee) field with contact autocomplete (ERP-ready)
- Entry threads: threadParentId links entries as replies, ThreadView shows
parent/current/children tree with branching support
- Info tooltips on deadline, status, and assignee fields
- New Resp. column and thread icon in registry table
- All changes backward-compatible with existing data