BREAKING CHANGES:
- Replace "Search Paperless Documents" buttons with "Link External Docs" across all modals
- Modal now supports multi-document linking without closing
NEW FEATURES:
- Multi-integration external document search modal with extensible architecture
- Immediate document population on modal open with pagination (15 docs/page)
- Support for linking multiple documents in single session
- Integration filter system (All Sources, Paperless NGX, etc.)
- Real-time search with 300ms debouncing
- Visual feedback for successfully linked documents
BACKEND CHANGES:
- Add /api/integrations/enabled endpoint to return active integrations
- Enhance integration system to support frontend filtering
FRONTEND ARCHITECTURE:
- Create ExternalDocManager class for centralized document search/linking
- Enhance ModalManager with attachExternalDocument() method for forward compatibility
- Maintain backward compatibility with existing attachPaperlessDocument()
UI/UX IMPROVEMENTS:
- Compact, centered modal design (60vh max-height, 700px max-width)
- Immediate document loading instead of empty search state
- Pagination controls with document count display
- Button state management (Link → Linked with checkmark and green styling)
- Modal subtitle explaining multi-document linking capability
- Success toast notifications with shortened display time
- Loading states and error handling throughout
TECHNICAL DETAILS:
- Extensible integration architecture for future additions (Nextcloud, SharePoint, etc.)
- CSS custom properties for consistent theming
- Responsive design with proper viewport centering
- Debounced search to prevent excessive API calls
- Proper state management for pagination and search queries
FILES MODIFIED:
- public/index.html: Update button text, add external doc modal structure
- public/styles.css: Add complete styling for external doc system
- public/script.js: Implement ExternalDocManager class with pagination
- public/managers/modalManager.js: Add attachExternalDocument method
- server.js: Add /api/integrations/enabled endpoint
This change transforms a Paperless-specific feature into a generic, extensible
multi-integration document linking system while maintaining full backward
compatibility and significantly improving user experience.
* feat: implement asset and component duplication feature (#79)
Add comprehensive duplication functionality allowing users to create multiple
copies of existing assets and components with sequential naming and sanitized data.
- **Duplicate Buttons**: Added duplicate buttons between Save/Cancel in asset and sub-asset modals
- **Smart Visibility**: Buttons only appear in edit mode (not when creating new items)
- **Sequential Naming**: Duplicates automatically named with incremental numbers (e.g., "Asset Name (1)", "Asset Name (2)")
- **Input Validation**: Users can create 1-100 duplicates with proper validation
- **Data Sanitization**: Excludes serial numbers, warranty info, files, and maintenance events from duplicates
- **Bulk Operations**: Efficient server-side bulk creation endpoints
- **public/index.html**:
- Added duplicate buttons to asset and sub-asset modal form-actions
- Added duplicate confirmation modal with count input
- Updated help text to explain sequential naming and data exclusions
- **public/styles.css**:
- Added styling for duplicate buttons with hover states
- Added duplicate modal and input styling
- Added responsive design support
- **public/managers/modalManager.js**:
- Extended with complete duplication functionality
- Added duplicate modal management methods
- Implemented sequential naming logic
- Added data sanitization for duplicates
- **public/script.js**:
- Added duplicate modal to escape key handler
- Added click-off-to-close functionality
- Exposed refreshAllData for ModalManager access
- **server.js**:
- Added `/api/assets/bulk` endpoint for bulk asset creation
- Added `/api/subassets/bulk` endpoint for bulk sub-asset creation
- Added validation for bulk operations (max 100 items)
- Added notification support for bulk operations
- Restored accidentally removed endpoints (settings, uploads, etc.)
- **Data Processing**: Strips sensitive data while preserving core asset information
- **Error Handling**: Comprehensive validation and user feedback
- **Performance**: Bulk server operations for efficiency
- **UX**: Loading states, success messages, keyboard shortcuts
Perfect for scenarios like:
- Creating multiple identical hard drives with different serial numbers
- Duplicating network equipment across locations
- Bulk adding similar components to inventory
- Setting up template assets for mass deployment
Resolves#79
* reorg styles.css
* Add properties grid to duplicate asset/subasset modal
* Add components and sub components duplication option to duplicate grid
* update file previews for subcomponents to support multiple file paths
* minor updates to duplicate modal styling
* update duplicate sub asset button icon
* Add duplicate button to asset / subasset actions
* apply svg styles to duplicate asset-actions buttons
* Fix component's sub component duplication
* Fix rendering proper asset / subasset after duplication
* refactor duplication/clone assets code into it's own manager class as well as closing asset modals after performing duplication
* fix asset navigation after duplicating an asset
---------
Co-authored-by: gitmotion <43588713+gitmotion@users.noreply.github.com>
* feat: add tag autocomplete with tab completion for asset/subasset modals
- Implement autocomplete dropdown for existing tags in asset and subasset tag fields
- Add tab completion functionality to quickly select suggested tags
- Include keyboard navigation (arrow keys, tab, enter, escape)
- Support mouse click selection of autocomplete suggestions
- Add getAllExistingTags() function to collect tags from all assets/subassets
- Enhance setupTagInput() with autocomplete container management
- Style compact dropdown with theme-aware background colors
- Update input placeholders to indicate new tab completion feature
- Maintain backward compatibility with existing tag input methods
Closes#84
* fix: correct undefined CSS variable in tag autocomplete background
Replace undefined var(--bg-color) with var(--background-color) in
.tag-autocomplete rule. This fixes theme-aware background styling
that was being ignored due to the invalid CSS property, ensuring
proper light/dark theme compatibility for tag dropdown menus.
* fix: make mobile keyup handler consistent with autocomplete selection
The keyup handler for Enter key (used primarily for mobile keyboards)
now properly checks for and applies selected autocomplete suggestions
instead of always adding the raw input value as a tag. This ensures
consistent behavior with the keydown handler and prevents incorrect
tag creation when users have navigated to autocomplete suggestions.
* fix: correct tag input autocomplete dropdown positioning
The autocomplete dropdown was appearing at the bottom of the form group
instead of directly below the input field. Fixed by:
- Using absolute positioning with proper viewport calculations
- Accounting for page scroll offset
- Dynamically updating position when dropdown is shown
- Appending to document.body for proper z-index layering
- Setting appropriate z-index to appear above other elements
The dropdown now appears directly below the input field as expected.
* comment fixes
* apply prettier rules
---------
Co-authored-by: gitmotion <43588713+gitmotion@users.noreply.github.com>
* Add date filtering to events table
Add past events to date filtering - still need to address infinite maintenance events
update all filter to only show all future and updating downdown text
* fixed the date rollover bug
Summary
I have successfully fixed the date rollover bug in the collectEventsInRange method in public/managers/dashboardManager.js. Here's what was fixed:
Issues Fixed:
Date Rollover Bug: The original code used futureLimit.setMonth(now.getMonth() + monthsAhead) which could cause incorrect date calculations when the current date was near the end of the month. For example:
January 31st + 1 month would become March 2nd instead of February 28th/29th
This could exclude valid events from the filter range
Dead Code: Removed unused variables pastLimit and showPast that were declared and assigned but never used in the filtering logic.
* fix: generate all recurring event instances in dashboard events list - Fixed dashboard events only showing nextDueDate for recurring maintenance - Now displays ALL occurrences of recurring events within selected date range - Added generateRecurringEvents() method to create multiple event instances - Added addTimePeriod() method for robust date arithmetic with rollover protection - Fixed past events logic to work forward from nextDueDate instead of backward - Supports all frequency types: daily, weekly, monthly, yearly events - Includes safety limits (max 100 events) to prevent infinite generation - Resolves issue where daily maintenance showed only 1 event instead of full schedule
* Implemented event list filtering via search bar
feat: add search and filter integration to events section
- Events now filter based on current search query and dashboard filters
- Only shows events for assets/sub-assets visible in the asset list
- Adds real-time event refresh when search input changes
- Maintains contextual relevance between asset list and events display
- Improves user experience by showing only relevant events
* Add specific date selector in events table
* show date picker on select of specific date
* Add light/dark awareness to calendar backgrounds and stroke color to calendar icon
* Add upcoming maintenance events line chart
* Add some math calculations to the charts to set min, max, stepsize
update stepsize to / 10 in case of divide by 0 error
update max by maxEvents + step size so it scales accordingly to the y axis
update min calculation
* add event date check
* adding maxEvents calculation to generateRecurringEvents for at least each day of the month times the number of monthsAhead (defaulted to 12)
add up to 100 events per day
update calculation
update default max events calculation
---------
Co-authored-by: abite <aleksbite@yahoo.com>
* Added Multi-file uploads
Allows users to upload multiple files for each file type.
Reworked cascading deletion logic to ensure Deleting an asset deletes all attachments as well as sub and sub sub assets and applicable attachments.
* Added file names as file-label
change file label to be file name, limited to 15 characters then cuts off.
* Fix removed features
Fixed Issues:
1. Asset Update Endpoint (PUT /api/assets/:id)
✅ Added name validation: Now validates that updatedAssetData.name exists before proceeding
✅ Added edit notification logic: Checks notificationSettings.notifyEdit and sends notifications when assets are edited
✅ Added debug logging: Logs asset update events when DEBUG mode is enabled
2. Sub-asset Update Endpoint (PUT /api/subassets/:id)
✅ Added name validation: Now validates that updatedSubAssetData.name exists before proceeding
✅ Added edit notification logic: Checks notificationSettings.notifyEdit and sends notifications when sub-assets are edited
✅ Added debug logging: Logs sub-asset update events when DEBUG mode is enabled
3. Asset Delete Endpoint (DELETE /api/asset/:id)
✅ Added delete notification logic: Checks notificationSettings.notifyDelete and sends notifications when assets are deleted
✅ Added debug logging: Logs notification attempts when DEBUG mode is enabled
4. Sub-asset Delete Endpoint (DELETE /api/subasset/:id)
✅ Added delete notification logic: Checks notificationSettings.notifyDelete and sends notifications when sub-assets are deleted
✅ Added debug logging: Logs notification attempts when DEBUG mode is enabled
Key Features Restored:
Data Integrity: Name field validation prevents saving assets/sub-assets without names
Notification System: Complete notification support for edit and delete operations
Consistent API: All endpoints now follow the same pattern as the create endpoints
Error Handling: Proper error handling for notification failures (won't break the main operation)
Debug Support: Comprehensive logging for troubleshooting when DEBUG=TRUE
* Reworked file label and preview grid formatting
* Fix file duplication on drag and drop
There are two separate drag and drop implementations that both trigger when files are dropped:
First implementation: In setupFileInputPreview() (lines ~105-140) - this sets up drag and drop for each individual upload box
Second implementation: In setupDragAndDrop() (lines ~300-389) - this also sets up drag and drop for all upload boxes
Both functions are being called, and they're both adding event listeners to the same elements, causing files to be processed twice. The fix is to remove the duplicate drag and drop code from setupFileInputPreview() since setupDragAndDrop() handles it more comprehensively.
* Fix file duplication on second drag & drop
The Solution:
Added file tracking: Each setupFileInputPreview() function now maintains a processedFiles Set that tracks which files have already been processed using a unique identifier.
Unique file identification: Each file is identified by ${file.name}-${file.size}-${file.lastModified}, which creates a unique fingerprint for each file.
Skip already processed files: Before creating a preview, the handler checks if the file has already been processed and skips it if so.
Clean up on deletion: When a file is deleted, its ID is removed from the processedFiles Set so it can be re-added later if needed.
* feat: completely rework file upload system to prevent duplicates and fix state issues
- Add comprehensive file state tracking with allFiles, newFilesSet, and filePreviewMap
- Implement additive file selection behavior for both drag-and-drop and file input
- Add deduplication logic to prevent duplicate files across multiple selections
- Create distinction between new files (for upload) vs existing files (preview only)
- Add reset() functionality to prevent state contamination between modal operations
- Fix existing file preview display by using server paths instead of mock File objects
- Fix individual file deletion by integrating with filesToDelete system using deletion markers
- Update handleFileUploads to only upload truly new files, preventing re-upload of existing files
- Add setupExistingFilePreview() for proper existing file integration with new helpers
- Update modal manager to use new helper functions and proper state clearing
- Add robust error handling and backward compatibility fallbacks
Fixes:
- File duplication when editing existing assets
- Missing image previews for existing files in edit modal
- Broken individual file deletions
- State persistence contamination between different asset operations
- Inconsistent behavior between drag-and-drop and file input selection
The file upload system now properly handles all edge cases while maintaining
a clean, predictable state across different operations.
* Add logic for import file drag and drop and restricting to single file
remove single attribute
adding self reference to eventlisteners for drag and drop
simplifying resetfileupload per file input
---------
Co-authored-by: gitmotion <43588713+gitmotion@users.noreply.github.com>
* Add hyperlink icon to asset details
Add hyperlink icon in both asset and sub asset details allowing users to copy a direct link to icons for barcode/QR code compatibility.
* Fix render timing to fix query param
I've resolved the query parameter timing issue by:
1. Fixed Initialization Order
Moved dashboardManager initialization before handleUrlParameters() is called
Removed duplicate dashboard manager initialization
Removed premature dashboard rendering in loadAllData()
2. Ensured Proper Flow
Data loads first (loadAllData())
Dashboard manager gets initialized with all dependencies
URL parameters are processed with all managers ready
Only if no URL parameters are found does the dashboard render
* Update README.md
Added maintenance feature
Added tagging feature
Added dependencies
* Include Global filters for Event List
Enhanced updateEventsDisplay() method - Now respects both local events filters (All, Warranty, Maintenance) AND global dashboard filters (Components, Warranties, Expired, Within 30 days, Within 60 days, Active)
Updated Dashboard Card Click Handlers - Now call updateEventsDisplay() when dashboard filters are applied
Enhanced initializeEventsSection() - Ensures events are properly filtered from the start
Added refreshEventsDisplay() method - Public method for external refreshing of events
* Updated/Fixed "Active" filtering logic
The "Active" filter had an incorrect third condition that was including assets with ANY component warranties, regardless of whether those warranties were actually active or expired.
* Fixed EventList updating
The issue was that sectionVisibility was a local variable in the renderDashboard method, so it wasn't accessible in the click handler scope when the dashboard cards were clicked later.
* add logging for event list debug
* Fix Event List updating
The Problem
The Events list wasn't updating when global dashboard filters were clicked because of a variable scope issue:
Two separate dashboardFilter variables existed:
One in main script.js (returned by getDashboardFilter())
One in listRenderer.js (updated by updateDashboardFilter())
The dashboard manager was reading from one variable but updating another:
getDashboardFilter() returned the main script's dashboardFilter (always stayed "all")
updateDashboardFilter() updated the list renderer's dashboardFilter
The Fix
I created a local updateDashboardFilter function in the main script that:
Updates the local dashboardFilter variable (the one getDashboardFilter() returns)
Calls the list renderer's updateDashboardFilter to keep both in sync
* Implement Export Function
Add export CSV functionality into Settings > System modal
* Fixed export button
Problem: The middleware/demo.js file was using ES6 export syntax, but the server was importing it using CommonJS require()
* export UI update
* Add simple csv export
* Removed placeholder logos with correct
Removed placeholder logos and placed real logo into public > assets > images
* remove white background from logo svg
* enlarge svg logo
* Include asset name with Warranty notifications
Add asset bane to warranty notifications so its formatted as:
⏰ Warranty Expiring in 7 days
Asset: Dell OptiPlex 7010
Model #: OptiPlex-7010
Warranty
Expires: 2024-01-15
🔗 View Asset: http://localhost:3000?ass=12345
* Update event list color thresholds
Updated dashboard event list threshold to:
Urgent 0-30 days
Warning 30-60 days
in order to match our alert icons in the asset list.
* Fix enter key on mobile
Key Benefits
Mobile compatibility: Mobile keyboards now show "Enter" button correctly
Multiple input methods: Supports Enter key, comma separation, and real-time comma detection
Form safety: Added stopPropagation() to prevent accidental form submissions
Cross-platform consistency: Works identically on desktop and mobile
Better UX: Users can add tags immediately without switching input methods
* Fixed "Component Details" title overlap
Key Benefits
No More Overlap: The Component Details header no longer covers the asset name and back button
Better Space Utilization: Reduced padding and font sizes create more breathing room
Improved Mobile UX: The header is now appropriately sized for mobile screens
Maintained Functionality: All buttons and text remain clearly visible and clickable
Responsive Design: The changes only apply on mobile (max-width: 853px) and don't affect desktop layout
Fix save subasset child modal and delete approriate files for those subassets and subassetchildren
Refactor and simply delete and update logic for assets and subassets
update import for url example
add resetImportForm to window from importmanager instead of script.js
update subasset file attachment expand/collapse to before showing the modal
match accepted file types from frontend to backend for manuals
update deleteAssetFileAsync with early return and to work with starting "/" or without
Add new toast manager with stacking toasts with success and error colors and repositioned to top
set button loading to false on subasset form validation
revert index.html change
initialize settings with default and copy over settings to always make sure all properties are included
remove unused async from createWarrantyDashboard function
The sub-asset editing was failing with a 404 "Sub-asset not found" error because the collectSubAssetFormData() method was incorrectly handling the sub-asset ID. It was trying to get the ID from a form field (document.getElementById('subAssetId')?.value) instead of using the actual existing sub-asset's ID when in edit mode.
The Fix:
I updated the collectSubAssetFormData() method in public/managers/modalManager.js to follow the same pattern as the asset form:
Edit Mode: When this.isEditMode is true and this.currentSubAsset exists, use this.currentSubAsset.id
Create Mode: When creating a new sub-asset, generate a new ID with this.generateId()
Changes Made:
Fixed the ID assignment logic to use this.currentSubAsset.id in edit mode instead of trying to read from a form field
Added debugging logs to help track the ID assignment process
Ensured the same pattern is used as the working asset form
Clickable Tags in Asset List Sidebar
Tags in the asset list sidebar are now clickable
Clicking a tag sets the search input to filter by that tag
Added data-tag attributes and click event listeners