shared_component 1.4.6+66.9.2
shared_component: ^1.4.6+66.9.2 copied to clipboard
A Flutter package that provides utilities for managing generic widgets for all modules.
simpliWORKS™ Shared Component Framework #
The shared_component package is the foundational enterprise UI toolkit and utility layer for the multi-module simpliWORKS™ ERP suite (spanning CRM, Expense, Store, Deliver, Finance, Master, Recycle, Resolve, and future modules).
1. Overview & Architectural Philosophy #
The primary objective of shared_component is to deliver:
- Maximum Reuse: High-quality, robust components shared seamlessly across business domains.
- Visual & Behavioral Consistency: Unified typography, spacing, styling, animations, and micro-interactions.
- Maintainability & Testability: Single-point bug fixes and standardized test coverage across all ERP modules.
- Zero Module Coupling:
shared_componenthas zero dependencies on business modules.
┌─────────────────────────────────────────────────────────────────────────────┐
│ simpliWORKS™ ERP Modules │
│ (CRM, Expense, Deliver, Store, Finance, Master, Recycle, Resolve, etc.) │
└──────────────────────────────────────┬──────────────────────────────────────┘
│ (Depends Strictly One-Way)
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ package:shared_component │
│ ├── Widgets (Buttons, Cards, Dialogs, Dropdowns, Feedback, Form, Layout) │
│ ├── Controllers (Theme, Font, Session, Security, Role, Dropdowns) │
│ ├── Utilities (Toast, Export, Validation, Numbers, Dates, Storage) │
│ ├── Monitoring & Telemetry (ApiInterceptor, ErrorTracker, Dashboard) │
│ └── Theming & Localization │
└─────────────────────────────────────────────────────────────────────────────┘
Important
Core Principle: Share what is genuinely common. Keep what is genuinely module-specific.
shared_component is NOT a dumping ground. Screen reuse inside a single module does not warrant global sharing. Never place module-specific business workflows or hard-coded domain logic into this package.
2. Directory Structure #
shared_component/lib/
├── auth_middleware/ # Routing & session authentication guards
├── bindings/ # Initial GetX bindings (Login, Preferences)
├── charts/ # Syncfusion chart implementations (Bar, Line, Spline, Pie)
├── controllers/ # Shared GetX controllers (Session, Theme, Security, Role)
├── custom_plugins/ # In-tree vendored plugin forks (PlutoGrid, DropdownSearch)
├── data/ # Core generic DTO models (BaseModel, DropdownModel, UploadModel)
├── data_source/ # Weighbridge & unloading data sources (Protected domain)
├── datagrid/ # Reusable PlutoGrid and TrinaGrid wrappers
├── dependency/ # Global dependency injection container (GetIt setup)
├── gen/ # Auto-generated asset and font bindings
├── localization/ # Multi-language translation dictionaries & services
├── monitoring/ # Error tracking, UI route observing & telemetry dashboard
├── network/ # Dio HTTP client, interceptors & platform adapters
├── routes/ # Platform navigation factories & route registries
├── services/ # Device and background services (Location, File, Download)
├── theme/ # AppTheme definition, dynamic styling & ThemeService
├── ui/ # Full shared screen flows (Auth, Preferences, Address, Downloads)
├── utils/ # Pure formatters, validators, extensions, enums & constants
│ ├── app_extensions/ # Extensions on String, DateTime, BuildContext, Color, etc.
│ └── enums/ # Centralized enums (Appearance, Clients, Modules, etc.)
└── widgets/ # All reusable UI widgets categorized by single responsibility
├── buttons/ # AppButton, AppButton2, AppIconButton, AppBulkActionBar
├── cards/ # AppCard, AppSummaryCard, AppPropertyGrid, AppModernTile
├── dialogs/ # GenericDialogBox, ConfirmDialogBox, RoleManagerDialog
├── dropdown/ # AppDropdown<T>, AppMultiSelectDropdown<T>
├── feedback/ # LoadingIndicator, NoPermissionAvailable, NotFoundPage
├── filters/ # AppFilterPanel
├── form/ # AppTextFieldFormWidget, AppCheckBox, AppSwitch, AppRadioButton
├── hardware/ # BoomBarrier, InternalWeighing, OpenGate (Protected domain)
├── header/ # Header, HeaderWidget, AppWebHeader, Footer
├── images/ # AppNetworkImage, AppSvgViewer, AppProfileImage
├── layout/ # AppScaffold, AppContainer, ResponsiveLayout
├── misc/ # AppTimelineWidget, AppGoogleMap
├── navigation/ # SidebarXDrawer, AllAppsDrawer, EventsDrawer
├── pickers/ # AppMediaPicker, AppDatePicker, FilePickerWidget
└── security/ # SecurityLockWidget, PermissionWrapperWidget
3. Public API & Single-Import Pattern #
Downstream ERP modules must import the shared toolkit using the unified barrel imports:
// ✅ Primary import for all widgets, layouts, and core utilities
import 'package:shared_component/shared_component.dart';
// ✅ Optional lightweight import for pure utilities, formatters, and enums
import 'package:shared_component/utils/utils.dart';
4. Component Catalog & Quick Reference #
| Category | Component | File Path | Purpose & Best Use Case |
|---|---|---|---|
| Dropdowns | AppDropdown<T> |
lib/widgets/dropdown/app_dropdown.dart | Strongly-typed single select powered by TypeAhead with instant search, async querying & add-new. |
| Dropdowns | AppMultiSelectDropdown<T> |
lib/widgets/dropdown/app_multi_select_dropdown.dart | Multi-item selection with badge chips, search, and bulk select/clear. |
| Buttons | AppButton / AppButton2 |
lib/widgets/buttons/app_buttons.dart | Theme-aware button with built-in tap debouncing and loading state. |
| Buttons | AppBulkActionBar |
lib/widgets/buttons/app_bulk_action_bar.dart | Floating bulk action toolbar for multi-row data grid operations. |
| Forms | AppTextFieldFormWidget |
lib/widgets/form/app_text_field_form_widget.dart | Standard text input with integrated debouncing, search, and validation. |
| Cards | AppSummaryCard |
lib/widgets/cards/app_summary_card.dart | Responsive key-value summary widget for entity overviews. |
| Cards | AppPropertyGrid |
lib/widgets/cards/app_property_grid.dart | Grid of key-value pairs with built-in copy-to-clipboard actions. |
| Cards | AppCard |
lib/widgets/cards/app_card_widgets.dart | Theme-aware container supporting Glassmorphism and dynamic elevations. |
| Dialogs | GenericDialogBox |
lib/widgets/dialogs/app_dialogs.dart | Standard modal dialog with responsive sizing and primary/secondary actions. |
| Dialogs | ConfirmDialogBox |
lib/widgets/dialogs/app_dialogs.dart | Confirmation prompt for destructive actions (Delete, Void, Cancel). |
| Feedback | LoadingIndicator |
lib/widgets/feedback/loading_indicator.dart | Configurable multi-style spinner with modal barrier backdrop. |
| Feedback | NoPermissionAvailable |
lib/widgets/feedback/no_permission_available.dart | Standardized 403 Forbidden state with back/home navigation actions. |
| Feedback | NotFoundPage |
lib/widgets/feedback/not_found_page.dart | Standardized 404 Route Not Found screen. |
| Filters | AppFilterPanel |
lib/widgets/filters/app_filter_panel.dart | Dynamic multi-field filter panel (text, dropdown, date-range, boolean). |
| Grids | EditablePlutoGridWidget |
lib/datagrid/editable_pluto_grid_widget.dart | High-performance enterprise datagrid with pagination, search, and inline editing. |
| Pickers | AppMediaPicker |
lib/widgets/pickers/app_media_picker.dart | Web & Mobile cross-platform file/image upload with thumbnail previews. |
| Timeline | AppTimelineWidget<T> |
lib/widgets/misc/app_timeline_widget.dart | Responsive audit trail and status tracking (horizontal on Web, vertical on Mobile). |
| Layout | AppScaffold |
lib/widgets/layout/app_layout_widgets.dart | Enterprise scaffold handling SidebarX drawers, global headers, and theme padding. |
5. Usage Examples #
A. Generic Single Dropdown (AppDropdown<T>) #
AppDropdown<CustomerModel>(
hintText: 'Select Customer',
items: controller.customers,
selectedItem: controller.selectedCustomer.value,
itemLabel: (customer) => '${customer.code} - ${customer.name}',
filterFn: (customer, query) =>
customer.name.toLowerCase().contains(query.toLowerCase()) ||
customer.code.toLowerCase().contains(query.toLowerCase()),
onChanged: (customer) => controller.onCustomerSelected(customer),
showSearch: true,
showAddNew: true,
addNewLabel: 'Add New Customer',
onAddNew: () => controller.openAddCustomerDialog(),
)
B. Generic Multi-Select Dropdown (AppMultiSelectDropdown<T>) #
AppMultiSelectDropdown<BranchModel>(
hintText: 'Select Branches',
items: controller.branches,
selectedItems: controller.selectedBranches,
itemLabel: (branch) => branch.branchName,
onChanged: (selectedList) => controller.updateBranches(selectedList),
)
C. Standard Form Input (AppTextFieldFormWidget) #
AppTextFieldFormWidget(
hint: 'Enter Voucher Number',
controller: controller.voucherNoTextController,
keyboardType: TextInputType.text,
isValidator: true,
validationMessage: 'Voucher number is required',
onChanged: (val) => controller.onVoucherChanged(val),
)
D. Modal Dialog (GenericDialogBox) #
Get.dialog(
GenericDialogBox(
headerText: 'Approve Expense Voucher',
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
AppText('Are you sure you want to approve Voucher #V-2026-001?'),
const SizedBox(height: 12),
AppTextFieldFormWidget(
hint: 'Remarks (Optional)',
controller: controller.remarksController,
),
],
),
primaryButtonText: 'Approve',
onPrimaryButtonPressed: () => controller.submitApproval(),
secondaryButtonText: 'Cancel',
onSecondaryButtonPressed: () => Get.back(),
),
);
E. Entity Summary Card (AppSummaryCard) #
AppSummaryCard(
title: 'Lead Information',
crossAxisCount: 3,
items: [
AppSummaryItem(label: 'Lead Code', value: lead.code),
AppSummaryItem(label: 'Contact Person', value: lead.contactPerson),
AppSummaryItem(label: 'Phone', value: lead.mobileNo, icon: Icons.phone),
AppSummaryItem(
label: 'Status',
valueWidget: AppBadge(text: lead.status, color: Colors.green),
),
],
)
F. Dynamic Filter Panel (AppFilterPanel) #
AppFilterPanel(
title: 'Filter Dispatches',
fields: [
FilterField(key: 'search', label: 'Search Query', type: FilterFieldType.text),
FilterField(
key: 'status',
label: 'Dispatch Status',
type: FilterFieldType.dropdown,
options: [
FilterFieldOption(label: 'Pending', value: 'PENDING'),
FilterFieldOption(label: 'In Transit', value: 'IN_TRANSIT'),
FilterFieldOption(label: 'Delivered', value: 'DELIVERED'),
],
),
FilterField(key: 'dateRange', label: 'Date Range', type: FilterFieldType.dateRange),
],
onApply: (filters) => controller.applyFilters(filters),
onReset: () => controller.clearFilters(),
)
G. Cross-Platform Media Upload (AppMediaPicker) #
AppMediaPicker(
label: 'Attach Proof of Delivery',
maxFiles: 5,
maxFileSizeMB: 10,
allowMultiple: true,
onFilesChanged: (files) => controller.uploadedFiles.assignAll(files),
)
H. Centralized Utilities & Toast Notifications #
// Toast notifications
AppToast.success(context, title: 'Saved', message: 'Record created successfully');
AppToast.error(context, title: 'Failed', message: 'Could not connect to server');
// Form Validation
String? error = AppValidators.email('invalid-email');
// Number & Currency Formatting
String formattedPrice = AppNumberUtils.formatCurrency(1250000.50); // ₹ 12,50,000.50
// Excel & CSV Export
await AppExportUtils.exportToExcel(
fileName: 'Dispatches_Report',
sheetName: 'Dispatches',
headers: ['ID', 'Vehicle', 'Driver', 'Status'],
data: dispatches.map((d) => [d.id, d.vehicleNo, d.driverName, d.status]).toList(),
);
6. Architecture Rules & Guidelines #
A. State Management Boundary #
- Stateless UI: Shared components must not maintain long-lived business state. Use
StatelessWidgetorStatefulWidgetstrictly for local UI interactions (animations, dropdown menu overlay state, text focus). - GetX Separation: Module business state belongs in module-level
GetxControllerinstances. Shared components communicate viaValueChanged<T>,VoidCallback, or builder delegates.
B. Business Logic & API Boundary #
✅ Correct Flow:
UI View ──> Module Controller ──> Module Service/Repo ──> Shared ApiService (Dio)
❌ FORBIDDEN:
Shared Widget ──> Direct Business Module API Calls
C. Generic Design vs Anti-Patterns #
| ❌ Anti-Pattern (Never Do This) | ✅ Recommended Pattern |
|---|---|
if (module == 'CRM') { ... } |
Pass configuration flags or callback delegates. |
Hard-coding domain DTOs (LeadModel, ExpenseModel) in shared widgets. |
Use generic types (AppDropdown<T>) with itemLabel and filterFn. |
| Creating duplicate widgets with minor styling differences. | Parameterize styling or wrap with AppCard / AppContainer. |
Leaving ScrollController or TextEditingController undisposed. |
Always clean up controllers and stream subscriptions in dispose() / onClose(). |
7. Decision Tree: Reuse, Extend, or Create? #
flowchart TD
Start["New UI Requirement"] --> Search["1. Search package:shared_component"]
Search --> Found{"Suitable component found?"}
Found -- "Yes (100% fit)" --> Reuse["✅ Direct Reuse"]
Found -- "Almost (needs small generic tweak)" --> Extend["⚠️ Extend component with optional generic parameter"]
Found -- "No" --> IsGeneric{"Is the requirement truly cross-module generic?"}
IsGeneric -- "Yes (Used by 2+ modules)" --> Create["✨ Create new component in shared_component/lib/widgets/"]
IsGeneric -- "No (Module-specific workflow)" --> ModuleOnly["📦 Keep inside <module>/lib/<module>_app/ui/"]
8. Protected Hardware & Weighbridge Domain #
The following components and controllers provide mission-critical hardware communication (boom barriers, weighbridge scales, RFID scanners) and must not be refactored without explicit hardware domain sign-off:
- lib/widgets/hardware/boom_barrier_widget.dart
- lib/widgets/hardware/internal_weighing_widget.dart
- lib/widgets/hardware/weighing_open_gate_functionality.dart
- lib/controllers/internal_transfer_weighing_controller.dart
- lib/data_source/new_weighing_sizes_data_source.dart
9. Developer Pre-Commit Checklist #
Before submitting changes to shared_component:
- ❌ Grep Usages: Checked all 8+ consuming ERP modules for breaking changes.
- ❌ Backward Compatibility: Preserved existing method signatures and exports in
shared_component.dartandutils.dart. - ❌ Zero Module Dependencies: Verified no imports of
crm_module,expense_module,deliver_module, etc. exist inshared_component. - ❌ Memory Safety: Verified all controllers, focus nodes, and listeners are properly disposed in
dispose()/onClose(). - ❌ Static Analysis: Executed
flutter analyzeor Dart analyzer with 0 errors and 0 warnings. - ❌ Unit Tests: Verified unit and widget tests pass (
flutter test).