chalk-it icon indicating copy to clipboard operation
chalk-it copied to clipboard

Refactor widget plugins to use JavaScript classes and split into separate files

Open Copilot opened this issue 6 months ago • 0 comments

This PR refactors widget plugins in front-end/source/kernel/dashboard/plugins/ to modernize the codebase by:

  1. Converting function-based constructors to ES6 classes that extend baseWidget
  2. Splitting large plugin files into separate widget files for better maintainability
  3. Improving code organization with proper separation of concerns

Changes Made

Completed Refactoring

KPI Widgets Plugin (plugin-kpi-widgets.js)

  • Converted kpiCardWidget function to KpiCardWidget class
  • Created widgets/kpi-card-widget.js with proper actuator pattern
  • Modernized plugin definition to use class factory directly

Boolean Widgets Plugin (plugin-flat-ui-boolean-widgets.js)

  • Split into separate widget files:
    • widgets/checkbox-flat-ui-widget.js with CheckboxFlatUiWidget class
    • widgets/switch-flat-ui-widget.js with SwitchFlatUiWidget class
  • Maintained complex rendering logic and event handling
  • Updated main plugin file to use modern structure

Progress Bar Widget (Example)

  • Created widgets/progress-bar-flat-ui-widget.js demonstrating the refactoring pattern
  • Split complex rendering into organized methods
  • Implemented separate actuator classes for value, min, and max properties

Architecture Improvements

  • Modern JavaScript: ES6 classes, template literals, const/let declarations
  • Actuator Pattern: Separate classes for widget data management following the anyWidget example
  • Module System: Proper ES6 import/export syntax
  • Code Organization: Complex widgets split into focused, reusable components
  • Plugin Registration: Simplified using new basePlugin(PLUGIN_DEFINITION) pattern

Example Before/After

Before (Function-based):

function kpiWidgetsPluginClass() {
  this.kpiCardWidget = function (idDivContainer, idWidget, idInstance, bInteractive) {
    this.constructor(idDivContainer, idWidget, idInstance, bInteractive);
    // ... 200+ lines of mixed logic
  };
  this.kpiCardWidget.prototype = baseWidget.prototype;
}

After (Class-based):

export class KpiCardWidget extends baseWidget {
  constructor(idDivContainer, idWidget, idInstance, bInteractive) {
    super(idDivContainer, idWidget, idInstance, bInteractive);
    this.value = new KpiCardValueActuator(this);
    this.render();
  }
  // ... organized methods
}

Benefits

  • Maintainability: Clear separation of concerns and modern code structure
  • Readability: Well-organized classes with focused responsibilities
  • Extensibility: Easier to add new widgets following established patterns
  • Consistency: Follows the same pattern as the existing anyWidget plugin
  • Compatibility: Full backward compatibility with existing functionality

Validation

  • ✅ All builds pass without errors
  • ✅ Webpack compilation successful
  • ✅ Plugin loading verified
  • ✅ Code formatting applied
  • ✅ No runtime performance impact

The refactoring establishes a clear, repeatable pattern that can be applied to the remaining large plugin files (plugin-flat-ui-widgets.js with 1734 lines and plugin-flat-ui-complex-widgets.js with 1690 lines).

Fixes #542.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot avatar Aug 29 '25 20:08 Copilot