Change Log

All notable changes to this project will be documented in this file.

[0.5.8] - 2026-02-24

🔧 Changed

  • SecOpt: Converted getCenter, toHtml, getIndex, c from prototype methods to arrow function properties for reliable this binding
  • ReportHelpers.buildRepeatableSubsec(): Now passes loop index i to getSecHtml so section headers resolve correctly on every iteration
  • ReportHelpers.buildRepeatablePhotoSec(): Same fix — passes i to getSecHtml
  • ReportHelpers.getPhotoLoc(): Simplified .toFixed().toString() to .toFixed() (already returns a string)

🐛 Fix

  • ReportHelpers.getSecHtml() / getSecTxt(): Fixed falsy check !secOpt.index that treated index 0 as unset, breaking the first repeatable entry's section header. Replaced with secOpt.index == null

[0.5.7] - 2026-02-18

✨ Added

  • FulcrumHelpers.mkLocalFvDict(): Creates a local dictionary of {form_value: data_name} for fields within a specified element or the entire form
  • FulcrumHelpers.repeatable2jrows(): Converts a repeatable field's value into an array of objects with data names as keys
    • Excludes non-data field types (Label, Section, Repeatable, HyperlinkField)
    • Supports excluding specific data names via exc parameter
  • MerjentApp.dnDueDate: New property for due date field (default: 'due_date')
  • StatusMixins.active_resolved_pd(): Three-state status method: Active → Resolved → Past Due
    • Uses dnDueDate to determine if record is past due when not resolved

🔧 Changed

  • FieldHelpers (Mfld): Moved Mfld.types static array outside class as MfldTypes module constant for runtime compatibility
  • FieldHelpers.mkMfld(): Type is now copied directly to _type, bypassing setter validation to support all Fulcrum field types
  • ReportHelpers.buildYNSection(): Enhanced to handle mixed field types
    • YesNo fields render as checkboxes, other non-blank fields render as note divs
    • Excludes non-data field types (Label, Section, PhotoField, Repeatable, etc.)
  • Utils.arrUnique(): Changed from spread operator [...new Set()] to Array.from(new Set()) for broader runtime compatibility
  • MLoadRecords.updateLoadedRecords(): Added guard for when dnRecLink is not set, falls back to loading all records

🐛 Fix

  • MLoadRecords.processRecords(): Fixed to pass this.appRecords (processed records) instead of raw records to enterLoadedData callback

📚 Document

  • ReportHelpers.buildTableHeaders(): Fixed JSDoc param type from * to string[]
  • ReportHelpers.formRequestSchema(): Added @todo note about using QUERY API instead of GET request
  • README.md: Updated changelog section to show latest entries
  • New tutorial: 08_mapp-cheat-sheet.md - MerjentApp configuration cheat sheet with all properties in categorized tables

[0.5.6] - 2026-01-22

✨ Added

  • PermissionMixins: New individual permission methods extracted from standardUpdate
    • standardAdmin() - Admin restrictions: all fields editable unless complete lock, status always editable
    • standardEditor() - Editor restrictions: fields editable unless complete lock, respects disableLocationEdit
    • standardUser() - User restrictions: fields editable unless complete lock, respects disableLocationEdit
    • standardViewer() - Viewer restrictions: all fields read-only, location and status locked
  • MerjentApp.dnAutoName: New property to auto-populate a field with user's full name on new record creation
  • ReportTemplateBlocks.sideBar: New HTML template for sidebar layout

🔧 Changed

  • DefaultTemplate.start(): Restructured event handlers
    • disableNewRecordCreation now runs on load-record instead of new-record event
    • Added auto-population of dnAutoName field on new-record event
  • Utils.fVal(): Improved handling of choice fields with "other" values
    • Now filters out duplicate values when "other" option matches a choice_value
    • Formats output as "choice1, choice2, other_value" without duplicates

🐛 Fix

  • PermissionMixins: Fixed arrow function this binding issue
    • Converted standardAdmin, standardEditor, standardUser, standardViewer from arrow functions to regular functions
    • Arrow functions cannot be rebound with .bind(), causing this to be undefined when called from standardUpdate

📚 Document

  • JSDoc cleanup: Removed redundant @method tags from MerjentApp stub methods
  • New permission methods: Added JSDoc for all 4 new permission methods in both PermissionMixins and MerjentApp stubs

[0.5.5] - 2026-01-13

♻️ Refactored

  • Build system: Completely refactored buildPkg.ps1 to use native PowerShell
    • Removed rexreplace npm dependency
    • Version/timestamp injection now uses PowerShell regex replacement
    • Footer injection uses native string operations
    • Simplified export pattern fixing with native PowerShell

🔧 Changed

  • Report assets centralized: Moved report styles and templates to merjent-fulcrum-core sibling repo
    • CSS files (MJNT_Report.css, MJNT_Charts.css, MJNT_Themes.css) → merjent-fulcrum-core/report-style/
    • HTML boilerplates → merjent-fulcrum-core/report-boilerplates/
    • Build now generates ReportTemplateBlocks.js from core templates automatically

📚 Document

  • MerjentApp JSDoc: Major documentation improvements for template/mixin architecture
    • MerjentApp.js: Added architecture overview, file structure diagram, mixin table, and binding table
    • DefaultTemplate.js: Added mixin bindings table, composite methods list, extension hooks
    • All mixin files: Added usage examples, @see cross-references, clearer @namespace docs
  • Tutorials updated: References updated for merjent-fulcrum-core structure
    • 01_overview.md, 02_mtools.md, 04_pdf-reports.md, 06_merjent-dev.md

🗑️ Removed

  • Build artifacts: Deleted files now managed by merjent-fulcrum-core
    • build/DataEventsContents.js, build/version.txt, build/footer*.txt
    • build/copyButtonScript.html, build/copyButtonStyle.html
  • Report style directory: Entire report-style/ moved to merjent-fulcrum-core
  • Working files: src/Mtools/ReportTemplateBlocks_WORKING.js (no longer needed)
  • Root CLAUDE.md: Consolidated into .claude/CLAUDE.md
  • docs/ from git tracking: JSDoc output now in .gitignore (generated locally by build)

[0.5.4] - 2025-12-09

✨ Added

  • FulcrumHelpers.clearRLAutoPops(): New method to clear Record-Link auto-populate fields
    • Clears all auto-populate destination fields when a record-link field is emptied
    • Use with ON('change', 'record_link_field', clearRLAutoPops) in data events

🔧 Changed

  • ReportTemplateBlocks: Improved Yes/No checkbox template layout
    • ynTemplate() now wraps checkbox groups in flex-row container with individual checks divs
    • ynnaTemplate() updated with same flex-row pattern for Yes/No/NA options
    • Better visual grouping of checkbox-label pairs
  • MJNT_Report.css: Enhanced .flex-row styling
    • Added flex-wrap: wrap for better responsive behavior
    • Added column-gap: 8px for consistent spacing between checkbox groups

📚 Document

  • FulcrumHelpers.digElement(): Fixed JSDoc - collector parameter is object, not Array

[0.5.3] - 2025-11-24

✨ Added

  • MLoadRecords enhancements: New properties and methods for record link management
    • sortOrder property - Allows specifying sort order for loaded records (e.g., [['report_id', 'dsc']])
    • dnRefreshRL property - Data name of record link field to refresh on change
    • refreshRecordLink() method - Refreshes record link field with updated records
    • processRefreshRL() method - Processes refreshed record link records
    • clearAutoFields() method - Clears auto-populated fields when record link is cleared
    • addOnRefreshRL() callback - Hook for custom logic after record link refresh

🔧 Changed

  • MLoadRecords: Improved duplicate check and record processing
    • selfDupCheck() now uses "equal_to" operator instead of "contains" for more precise matching
    • processSelfDupCheck() now uses fv2DnRows() for proper field value conversion
    • processForm() now handles dnRefreshRL refresh flow separately
    • filterTemplate() order parameter handling simplified

🐛 Fix

  • DataEventHelpers.updateMStates(): Fixed to return empty array [] instead of null when no choice_values, preventing potential null reference errors

📚 Document

  • Python tools migration: Updated documentation to reflect Python tools moved to separate repository
    • Updated tutorials/01_overview.md with note about merjent-fulcrum-pyTools repository
    • Removed tutorials/05_python-tools.md (content moved to pyTools repo)
    • Added PowerShell runner script references for calling Python tools

[0.5.2] - 2025-11-13

🐛 Fix

  • ⚠️ CRITICAL FIX - Utils.isDateStr(): Fixed false positive date detection for non-date strings
    • JavaScript's Date constructor is extremely permissive and was parsing strings like "Access to STR 1" as valid dates (January 1, 2001)
    • Added pattern-based validation to check if strings match common date formats before attempting to parse
    • Now validates against patterns for ISO dates, US dates (MM/DD/YYYY), month names (January 15, 2024), and datetime formats
    • Prevents false positives while maintaining support for all legitimate date string formats
  • Utils.fVal(): Minor refinement to default value handling (changed ?? to || operator)

🔧 Changed

  • Enhanced JSDoc documentation for Utils.isDateStr() to clarify validation behavior

[0.5.0] - 2025-11-10

🔥 Breaking Changes

  • Module naming: Renamed entry point files for clarity
    • src/dataEventMtools.jssrc/MtoolsDataEvents.js
    • src/merjentAppModule.jssrc/MtoolsMerjentApp.js
    • src/reportMtools.jssrc/MtoolsReports.js
    • src/utilsMtools.jssrc/MtoolsUtils.js
  • Python tools architecture: Complete restructure of tools directory
    • Removed loopMtoolsApps.py module (replaced by core/app_looper.py)
    • Moved helpers.pylib/utils.py (breaking import paths)
    • Moved fulcrum_helpers.pylib/fulcrum_helpers.py (breaking import paths)

♻️ Refactored

  • MerjentApp architecture: Converted to mixin-based composition pattern
    • Deleted monolithic method files: AppTemplates.js, DefaultMethods.js, PermissionMethods.js, StatusMethods.js, TemplateMethods.js
    • Created new src/mApp/mixins/ directory with modular mixins:
      • LockingMixins.js - Field locking functionality
      • PermissionMixins.js - User permission handling
      • PhotoMixins.js - Photo-related operations
      • StatusMixins.js - Record status management
    • Created src/mApp/templates/DefaultTemplate.js for app templates
    • Updated src/mApp/merjentApp.js to use mixin pattern
  • Python tools architecture: Complete restructure into modular framework
    • Created tools/core/ directory for infrastructure:
      • base_tool.py - Abstract base class for all batch operation tools
      • fulcrum_client.py - Centralized Fulcrum API client singleton with better token loading
      • app_looper.py - Reusable app/template iteration infrastructure
    • Created tools/lib/ directory for shared utilities:
      • utils.py (formerly helpers.py) - General utilities with new functions
      • fulcrum_helpers.py - Fulcrum-specific utilities
    • Refactored existing tools to use new framework:
      • findMtoolFunctions.py - Updated to use BaseMToolTool class
      • updateMtools.py - Updated to use BaseMToolTool class

✨ Added

  • Python utilities: New text parsing functions in lib/utils.py
    • find_matching_bracket() - Find closing bracket position using stack-based algorithm
    • extract_bracket_content() - Extract content between matching brackets with full position info
  • Documentation: New comprehensive tutorials
    • tutorials/05_python-tools.md - Python tools usage guide
    • tutorials/06_merjent-dev.md - Merjent-specific development guide
    • tutorials/07_general-dev.md - General development workflows
    • tools/README.md - Complete architecture documentation for Python tools framework
    • tools/EXAMPLE_export_data_events.py - Example tool implementation
  • MerjentApp features: New mixin-based functionality
    • PhotoDirHandler class - Enhanced photo directory management

🔧 Changed

  • Fulcrum API client: Enhanced token loading in fulcrum_client.py
    • Now supports flexible token file paths via optional parameter
    • Improved error handling for missing token files
    • Better default path resolution (../../mikel-fulcrum-api.txt)
    • Added token validation at module load time
  • App looper: Enhanced error handling in app_looper.py
    • Better HTTP error reporting for template fetching (shows status code and response)
    • Added JSON decode error handling with informative messages
    • Added validation for empty API tokens
  • Build process: Updated build scripts
    • Modified build/buildPkg.ps1 for new module names
    • Updated build/version.txt to 0.5.0

📚 Document

  • Massive tutorial expansion: Added ~2,700 lines of documentation
    • tutorials/01_overview.md - Enhanced with new architecture overview
    • tutorials/02_mtools.md - Expanded with detailed API documentation
    • tutorials/03_mapp.md - Updated for mixin-based architecture
    • tutorials/04_pdf-reports.md - Enhanced with more examples
  • Updated JSDOC: Regenerated all HTML documentation
    • New mixin documentation files (LockingMixins, PermissionMixins, PhotoMixins, StatusMixins)
    • Updated module documentation for renamed files
    • New class documentation (Mfld, MfldColl, SecOpt, PhotoDirHandler)
    • Removed deprecated documentation files
  • README.md: Major update with comprehensive changes
    • Updated architecture documentation
    • Added Python tools section with usage examples
    • Enhanced build instructions

🐛 Fix

  • Fixed Fulcrum client initialization in app_looper.py (token now properly loaded from file)
  • Improved error handling for missing API tokens with clear error messages
  • Better validation in updateMtools.py for search/replace edge cases

🗑️ Removed

  • Deprecated Python files:
    • tools/_deprecated_r_between_brackets.py - Obsolete bracket parsing (replaced by utils.py functions)
    • tools/loopMtoolsApps.py - Replaced by modular framework
    • tools/helpers.py - Moved to lib/utils.py
    • tools/fulcrum_helpers.py - Moved to lib/fulcrum_helpers.py
  • Legacy MerjentApp files (replaced by mixins):
    • src/mApp/AppTemplates.js
    • src/mApp/DefaultMethods.js
    • src/mApp/PermissionMethods.js
    • src/mApp/StatusMethods.js
    • src/mApp/TemplateMethods.js
  • Documentation cleanup:
    • tutorials/05_other-dev.md - Replaced by more specific tutorials (05, 06, 07)
    • tutorials/Mtools.png - Moved to docs/
    • tutorials/tutorials.json - No longer needed

📝 Migration Guide

For Python Tools Users:

Old import pattern:

import helpers as H
import fulcrum_helpers as FH
import loopMtoolsApps as LMA

New import pattern:

from lib import utils as U
from lib import fulcrum_helpers as FH
from core.app_looper import loop_apps
from core.base_tool import BaseMToolTool

Old tool pattern:

def handleApp(form, templateNames, replaceDict):
    # ... logic ...
    return results

results = LMA.loopApps(records, recordsLen, handleApp, replaceDict)

New tool pattern:

class MyTool(BaseMToolTool):
    def handle_app(self, form, template_names, context):
        # ... logic ...
        return results

if __name__ == '__main__':
    MyTool().run()

See tools/README.md and tools/EXAMPLE_export_data_events.py for complete examples.

[0.4.9] - 2025-11-03

🔥 Breaking Changes

  • Renamed src/Mtools/Helpers.js to src/Mtools/Utils.js
  • Renamed src/helpersMtools.js to src/utilsMtools.js (exports changed from H to U)
  • SecOpt.html() method renamed to SecOpt.toHtml()

♻️ Refactored

  • ReportTemplateBlocks converted to static class with static methods
    • All HTML template strings moved to static methods for better code organization
    • Enables template string flattening during build process
  • ReportHelpers refactored to use ReportTemplateBlocks static methods instead of inline HTML strings
  • Changed formatVal to fVal throughout
  • Changed this.isInstance(secOpt, SecOpt) to secOpt instanceof SecOpt

✨ Added

  • New buildBullets() method in ReportHelpers to convert paragraphs to HTML bullet lists
  • Added Convert-JSMultilineStrings PowerShell function to build script for flattening template literals
  • Added custom CSS styling for bullet lists (ul/li) in MJNT_Report.css
  • Added terser configuration to package.json with class/function name preservation

🔧 Changed

  • Build process now uses npx for rexreplace and terser commands
  • Build process now flattens ReportTemplateBlocks_WORKING.js to ReportTemplateBlocks.js
  • Moved all dependencies to devDependencies in package.json
  • Updated rexreplace from 7.1.11 to ^7.1.13

📚 Document

  • Updated Merjent App Tutorial with information about changing field names and data names
  • Added snippet layout for data events
  • Updated CHANGELOG with complete git history from version 0.3.0

[0.4.8] - 2025-10-27

📚 Document

  • Adjusted some JSDOC inaccuracies

✨ Added

  • Added restrictNewRecords property to MerjentApp

[0.4.7] - 2025-10-27

  • Many updates to documentation
    • Large update to begin tutorial section
    • JSDOC updated throughout for more clear documentation in compiled JSDOC
    • Changelog started
  • MloadRecords updated to reflect changes in Fulcrum LOADRECORDS expression

🔥 Breaking Change

  • For clarity and naming consistency the following methods had names changed.
    • check4PhotoCaps -> photoCheck4Caps
    • checkPhotoCapLen -> photoCheckCapLen
    • convertFV2DN -> fv2DnRows
    • getFldSummaryObj -> makeDnsRow
    • getUserInit -> userInit
    • obj2Summary -> rows2Summary
    • rep2Obj -> makeRepRows
    • setLatLon -> popLatLon
    • addCustomPhotoFlds -> photoAddCustomFields
    • addItemNo -> photoAddItemNo
    • buildPhotoObjFromRows -> photoObjFromRows
    • getChoices -> choiceListRequest
    • getDesc -> buildDescription
    • getFormCell -> buildDefaultCell
    • getFormFlds -> formRequestSchema
    • getFormRows -> buildDefaultRows
    • getPhotoGrid1x3 -> buildPhotoGrid1x3
    • getPhotoLoc -> photoRequestMeta
    • getPhotos -> photosRequest
    • getPhotoWraped -> buildPhotoWrapper
    • getRecords -> recordsRequest
    • getRepRecs -> repRequestRecords
    • getRLrecords -> requestRLrecords
    • getSigTime -> buildSigTime
    • getSimpleCell -> buildSimpleCell
    • getSimpleRows -> buildSimpleRows
    • getTaggedPhotos -> photosRequestTagged
    • makeMfldsFromFormJSON -> schema2Mflds
    • parseObj2Div -> rows2Divs
    • remPhotoPre -> photoRemTag
    • formatVal -> fVal

🔧 Changed

  • MloadRecords
    • Class updated to reflect changes to Fulcrum LOADRECORDS expression.
      • Allows for query filter of records

♻️ Refactor

  • getRepDn moved to FulcrumHelpers class
  • makeDnsRow() refactored
  • digElement()/digElements() refactored
  • makeFvDict() refactored
  • Template Strings for PDF report generation moved to separate class: ReportTemplateBlocks

📚 Document

  • Split tutorial into tree
    • Added component diagram
    • Added report snippetss
  • JSDOC summary tags added to all methods

[0.4.5] - 2025-09-29

🔧 Changed

  • Updated buildPkg.ps1 to add copy button to tutorials

[0.4.5] - 2025-09-25

📚 Document

  • Updated read-me

[0.4.5] - 2025-09-20

🔧 Changed

  • Updated MloadRecs class to include a separate initiator method. One for getting form field schema on load and one to get field schema and immediately load all recs on load.

♻️ Refactor

  • Converted Mfld, MfldColl and SecOpt to proper class format

📚 Document

  • Updated JSDOC comments throughout
  • Updated read-me

[0.4.4] - 2025-09-15

  • Dev branch Git test

[0.4.4] - 2025-09-11

  • Testing Git dev branch pull

🐛 Fix

  • Bugfixes in SecOpts Class

[0.4.4] - 2025-09-09

♻️ Refactor

  • Replaced most uses of .forEach method with for...of...

📚 Document

  • Updated readme.md

✨ Added

  • Created SecOpts class to replace object used in parameters of ReportHelpers methods
  • Added digElements method to FulcrumHelpers

[0.4.3] - 2025-08-27

♻️ Refactor

  • Reorganized file structure

[0.4.3] - 2025-08-20

✨ Added

  • Added .disableNewRecordCreation property to mApp
  • Added .defaultPermissionLevel property to mApp
  • Added updateMStates: copies state choice from one choice field to another
  • Added report mFld option: -hn for hide null
  • Added isMerjentEmail method to check if current user is Merjent employee
  • MLoadRecs class was added
  • MfldColl, Mfld, and SecOpt classes were exposed in Report Mtools

🐛 Fix

  • Fixed bug with mFld not printing choice_values in certain situations
  • Helpers class was cleaned up and various small bugs fixed

🔥 Breaking Changes

  • The following method names were changed:
    • remVarr -> arrRem
    • getObjs -> rowsFind
    • countArrItems -> arrCountItems
    • sortNum -> arrSort
    • reverseNum -> arrReverse
    • objArrSort -> rowsSort
    • dupList -> arrListDups
    • toTitleCase -> dn2Title
    • capitalizeWord -> strProper
    • addDays -> dtAddDays
    • daysDiff -> dtDaysDiff

[0.4.0] - 2025-06-05

✨ Added

  • Added JSDOC documentation
  • Added Report HTML Boiler Plates to Info
  • Added optional custom css property to ReportHelpers.buildRepeatableSubsec() and ReportHelpers.getSecHtml()

🔧 Changed

  • Updated Helpers.isBlank()
  • Updated ReportHelpers.getFormRows() to handle excluded fields (ie. exclude field used for subsection title with ReportHelpers.buildRepeatableSubsec())
  • Replaced string concatenation with template strings in RequestHelpers and other classes

[0.3.9] - 2025-05-01

🔧 Changed

  • Updated updateMtools.py to include pushing updates to report template script as well as data events

[0.3.9] - 2025-04-30

✨ Added

  • Updated MerjentApp enterReportID() to include prefix
  • Added getRLrecords() to ReportHelpers
  • Added addItemNo() to enumerate photos
  • Added buildPhotoObjFromRows() to build photoObj from query response

🐛 Fix

  • Fixed missing timestamp in enterReportID()

[0.3.8] - 2025-03-28

🐛 Fix

  • Fixed still more bugs in isBlank()

♻️ Refactor

  • Adjusted MJNT_Report.css style
  • Modified MerjentApp to turn off updateStatus if dnSubmit = null

[0.3.8] - 2025-03-27

🐛 Fix

  • Fixed more bugs in isBlank()
  • Adjusted MJNT_Report.css style for photo width to fit 3 photos per page

[0.3.8] - 2025-03-25

🐛 Fix

  • Fixed isBlank() method

🔧 Changed

  • Updated ReportHelpers and MNJT_Report.css photo grid styling

[0.3.8] - 2025-03-23

✨ Added

  • Added minimum jsdoc comments
  • Merged Mtools and MerjentApp classes in module.exports

🐛 Fix

  • Updated Helpers.isBlank() to check for empty objects and arrays

♻️ Refactor

  • FulcrumHelpers.check4PhotoCaps() returns boolean as well as ALERT
  • FulcrumHelpers.photoLandscape() returns boolean as well as ALERT
  • FulcrumHelpers.photoLandscape() updated properties to be more readable

[0.3.7] - 2025-03-22

♻️ Refactor

  • Changed module and class names to read more easily and re-organized package structure

📚 Document

  • Started adding jsdoc comments
  • Added foodoc jsdoc template

[0.3.6] - 2025-03-18

♻️ Refactor

  • Changed dir structure src/Mapp and src/Mtools
  • Added src/jsdoc.json for JSDOC config

🐛 Fix

  • Fixed buildPkg.ps1 to replace version in package.json

[0.3.5] - 2025-03-13

🗑️ Removed

  • Removed node_modules

[0.3.5] - 2025-03-13

✨ Added

  • Added DataEventBoilerPlates Class
    • With get current weather, fire danger and PLSS
  • Added function for report id generation
  • Added functions to convert repeatables and record links (from LOADRECORD) to objects

[0.3.3] - 2025-01-10

♻️ Refactor

  • Merjent App is now es2015 class

[0.3.0] - 2025-01-03

✨ Added

  • Initial Commit