Use this README as a Cascade prompt
A framework for building data-driven web applications with MATLAB integration, following a clean MVC architecture with vanilla JavaScript.
- Overview
- Project Structure
- Core Architecture
- Application Architecture
- View Architecture & Component System
- App Generator
- Testing
- Additional Notes
I am working on the templateAppFramework project. Please follow these rules and explanations to ensure consistency and maintainability:
templateAppFramework/
├── appFramework/ # Core framework (model, view, controller, utils)
├── appGenerator/ # Tools & templates for app creation
├── apps/ # User-created apps (not tracked in framework repo)
└── resources/ # Example/shared data (not tracked in framework repo)
- Purpose: Validates and manages model objects based on language-agnostic JSON class definitions.
- How it works:
- Reads JSON files from
data-model/(one per class) - Each JSON defines class name, parent, properties, types, etc.
- Ensures that all instantiated model objects conform to their definitions
- Supports inheritance: child classes extend parent definitions
- Reads JSON files from
- Usage: Used by the app at runtime to validate and construct model instances from JSON data.
- EventManager:
- Central hub for event dispatching and listening between components
- Supports registering listeners, emitting events, and removing listeners
- Decouples components, enabling modular and testable code
- EventListener:
- Interface/mixin for components to subscribe to and handle specific events
- Used by model, view, and controller classes to react to changes or user interactions
- Role: Represents the application's data on the client side
- Responsibilities:
- Loads model definitions and classes dynamically
- Instantiates model objects from JSON
- Handles synchronization with MATLAB via the HTML component API
- Provides APIs for querying and updating the model
- MATLAB Integration: Can receive/set data via MATLAB's
uihtmlinterface
-
AbstractApp (Base Class):
- Core application class that manages the application lifecycle
- Handles initialization of Model and View
- Manages communication with MATLAB when running in MATLAB environment
- Provides default implementations for common functionality
- Manages event subscriptions and dispatching
-
App Implementation (Subclass of AbstractApp):
- Each app must extend AbstractApp and implement required abstract methods:
class MyApp extends AbstractApp {
// Required: Return the root class name for model instantiation
getRootClassName() {
return 'MyRootClass';
}
// Required: Return the root folder path for model loading
getRootFolderPath() {
return 'myApp';
}
// Required: Return the application title
getAppTitle() {
return 'My Custom App';
}
// Optional: Override for custom view initialization
createView() {
return new CustomView({
app: this,
container: '#app',
title: this.getAppTitle()
});
}
// Optional: Override for custom model initialization
createModel() {
return new CustomModel({
app: this,
rootClassName: this.getRootClassName(),
rootFolderPath: this.getRootFolderPath()
});
}
}- Lifecycle:
- App instance is created
_initializeApp()is called automatically_createModel()and_createView()are called to instantiate components- Components are initialized in the correct order (model first, then view)
- App is ready for user interaction
index.htmlis minimal, containing only the root container and script tagsAbstractApp.jsis lightweight, delegating UI rendering to View classes- All UI elements are managed by View classes in the
view/directory
- AbstractView (base class in
appFramework/view/):- Holds a reference to the app instance (
this._app) - Manages the root DOM element (
this.element) - Owns a
Layoutinstance for component arrangement
- Holds a reference to the app instance (
- BasicView (example implementation) extends
AbstractView - App-specific views extend either
AbstractVieworBasicView
Layoutclass manages the page structure with configurable panels- Supports multiple regions: header, left sidebar, main content, right sidebar, bottom
- Components are placed into these regions using
_setComponent(position, element) - Handles responsive behavior and panel resizing
BaseComponentis the foundation for all UI components- Components are self-contained and receive their parent View instance
- Common components include:
ModelPanel: Displays and edits model dataToolstrip: Horizontal toolbar with buttonsLogConsole: Displays application logsJSONViewer: Shows JSON representation of data
- Reusable UI widgets in
appFramework/view/widgets/ - Examples:
TreeTable: Hierarchical data displayFormField: Input fields with validation
- Widgets are used by components to build complex interfaces
-
Purpose: Automates creation of new app skeletons with the correct structure
-
Current workflow:
- Create JSON model definition files (in a directory like
data-model/) - Mark your root model with
IsRoot=truein its JSON definition - From the project root, run:
This creates a new folder in
node appGenerator/utils/create-app.js <AppName> --data <path/to/example.json> --model-defs-dir <path/to/model-defs> [options]
/apps/<AppName>/with all required subfolders and:- Copies the example data file to resources/
- Copies model definition JSONs to the app's data-model/ directory without modification
- Generates proper MATLAB class files in server/model/+/
- Creates App.js with direct (non-relative) imports and proper model loading
- Generates ModelPanelConfig.json from model definitions
Available options:
--data <path>(required): Path to example JSON data file--model-defs-dir <path>: Path to directory containing model definition JSON files--root-class <className>: Name of the root class for the application (detected automatically if not specified)--forceor-f: Overwrite existing app if it exists--title <title>: Custom title for the application
- Create JSON model definition files (in a directory like
- The framework includes a comprehensive test suite using Jest
- Run all tests:
npm test - Run tests with coverage report:
npm run test:coverage
- Test files should be placed alongside the code they test with
.test.jssuffix
- Run live-server from the project root directory
- Open the server address provided in your browser
- Navigate to
apps/<AppName>/index.htmlin your browser
- In MATLAB, navigate to your app's directory
- Run the app using the appropriate MATLAB command
- The app should launch in a MATLAB figure window
- Test all MATLAB-specific functionality including:
- Data synchronization between MATLAB and the web view
- Event handling between MATLAB and JavaScript
- Error conditions and edge cases
- After creating a new app with the appGenerator:
node appGenerator/utils/create-app.js MyNewApp path/to/example.json
- Navigate to the app's directory
- Run the tests to verify the basic functionality:
cd apps/MyNewApp npm test
- Test the app in a browser as described above
- Use browser developer tools (F12) for client-side debugging
- Check the JavaScript console for errors and log messages
- For MATLAB integration issues, verify that:
- The MATLAB web component is properly initialized
- All required MATLAB toolboxes are installed
- The MATLAB path includes all necessary directories
- Documentation: Refer to
appGenerator/templates/README.mdfor up-to-date instructions and project structure. - promptLog Files*: For historical context, see the
promptLog_*files in the project root (not tracked by git).
If you need to add new features, fix bugs, or refactor, always follow these principles:
-
Vanilla JavaScript Only: Use ES modules, no frameworks or build tools (no React, Vite, Webpack, etc.)
-
Modular Design: All core logic is separated into modules (model, view, controller, utils)
-
Relative/Absolute Imports: Use import paths that work in a vanilla JS environment
-
Apps Are Modular: Each app is self-contained in
/apps/and can extend, but not modify, the core framework -
MATLAB Integration: Works with MATLAB's HTML component (
uihtml) and runs standalone -
Data Binding:
- ModelPanel components support automatic data binding to model objects
- Views can bind widgets to model properties via the Binding class
- Changes to model data trigger UI updates automatically via the Observer pattern
- Both simple properties and nested object paths are supported (e.g., 'parameters[0].value')
- Validation is performed automatically based on model property definitions
- Read-only properties are presented as non-editable fields in the UI
-
CSS Organization Strategy:
- Component-specific CSS: Each component with unique styling needs should have its own CSS file (e.g.,
ModelPanel.css,dropdown-button.css) - Shared/common CSS: Elements used across multiple components should be defined in
components.css(e.g.,.panel-header,.form-group) - Global layout: The
layout.cssfile contains global layout structure styles - CSS rule precedence: Component-specific CSS files should be the source of truth for their specific components
- Avoid duplication: Never define the same CSS class in multiple files
- Variables: Use CSS variables (defined in
:root) for consistent styling
- Component-specific CSS: Each component with unique styling needs should have its own CSS file (e.g.,
-
Build the Application: From the project root directory, run:
node build-matlab-package.js gPKPDSimConfigTool
This will:
- Minify all JavaScript and CSS files
- Copy all necessary files to the
dist/gPKPDSimConfigTool-distdirectory - Prepare the application for MATLAB packaging
-
Package for MATLAB: In MATLAB, navigate to the distribution directory and run:
cd /path/to/templateAppFramework/dist matlab.apputil.package('gPKPDSimConfigTool.prj')
Prerequisites:
- Ensure the
.prjfile is already created in thedistdirectory - MATLAB must be on your system path
- All required MATLAB toolboxes must be installed
- Ensure the
-
Output: The packaged application will be created as a
.mlappinstallfile in thedistdirectory.
-
Key Components:
- MATLAB uihtml component hosts the web app
- Server-side MATLAB model classes mirror JavaScript client-side models
- Path construction is environment-aware (browser vs MATLAB)
- Static resources (CSS, icons, JSON) are served correctly in both environments
-
Resource Paths:
- AbstractApp provides
getMatlabBaseUrl()which components should use for resource paths - Icons and CSS load properly in both browser and MATLAB environments
- Use SVG icons where possible for better cross-environment compatibility
- AbstractApp provides
-
Model Inheritance:
- Root classes inherit from
server.model.RootModel - All other model classes inherit from
server.model.BaseObject - App generator ensures proper inheritance when creating MATLAB class files
- Root classes inherit from
- The framework includes a comprehensive test suite using Jest
- Run all tests:
npm test - Run tests with coverage report:
npm run test:coverage
- Test files should be placed alongside the code they test with
.test.jssuffix
- Run live-server from the project root directory
- Open the server address provided in your browser
- Navigate to
apps/<AppName>/index.htmlin your browser
- In MATLAB, navigate to your app's directory
- Run the app using the appropriate MATLAB command
- The app should launch in a MATLAB figure window
- Test all MATLAB-specific functionality including:
- Data synchronization between MATLAB and the web view
- Event handling between MATLAB and JavaScript
- Error conditions and edge cases
- After creating a new app with the appGenerator:
node appGenerator/utils/create-app.js MyNewApp path/to/example.json
- Navigate to the app's directory
- Run the tests to verify the basic functionality:
cd apps/MyNewApp npm test
- Test the app in a browser as described above
- Use browser developer tools (F12) for client-side debugging
- Check the JavaScript console for errors and log messages
- For MATLAB integration issues, verify that:
- The MATLAB web component is properly initialized
- All required MATLAB toolboxes are installed
- The MATLAB path includes all necessary directories
- Testing: You can test apps in a web browser by serving the project root with a simple static server (e.g.,
npx serve .or Python'shttp.server). - Documentation: Refer to
appGenerator/templates/README.mdfor up-to-date instructions and project structure. - promptLog Files*: For historical context, see the
promptLog_*files in the project root (not tracked by git).
If you need to add new features, fix bugs, or refactor, always follow the modular, vanilla JS, and ES module principles described above. If you have questions about architecture or design, ask for clarification before making changes.