myio-js-library 0.1.21 → 0.1.23

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -945,6 +945,362 @@ The component includes premium MyIO styling with:
945
945
  - Responsive design for mobile and desktop
946
946
  - Portuguese month names and day abbreviations
947
947
 
948
+ ### Premium Date Range Input Component
949
+
950
+ #### `createInputDateRangePickerInsideDIV(params: CreateInputDateRangePickerInsideDIVParams): Promise<DateRangeInputController>`
951
+
952
+ Creates a complete, beautifully styled date range input inside a target DIV container, combining the functionality of `createDateRangePicker` with premium MyIO styling. This component automatically creates the HTML structure, injects styling, and provides a clean API for ThingsBoard widgets and other applications.
953
+
954
+ **Parameters:**
955
+ - `params: CreateInputDateRangePickerInsideDIVParams` - Configuration object:
956
+ - `containerId: string` - The DIV id where the input will be created (required)
957
+ - `inputId: string` - The id to set on the created input (required)
958
+ - `label?: string` - Optional label text (default: "Período de Datas")
959
+ - `placeholder?: string` - Input placeholder (default: "Clique para selecionar período")
960
+ - `pickerOptions?: CreateDateRangePickerOptions` - Pass-through options for createDateRangePicker
961
+ - `classNames?: object` - Custom CSS classes for wrapper, label, input, and helper
962
+ - `injectStyles?: boolean` - Inject premium MyIO styling (default: true)
963
+ - `showHelper?: boolean` - Show helper text with format info (default: true)
964
+
965
+ **Returns:** Promise resolving to `DateRangeInputController` object with:
966
+ - `input: HTMLInputElement` - The created input element
967
+ - `container: HTMLElement` - The target container element
968
+ - `wrapper: HTMLElement` - The wrapper element created by this component
969
+ - `picker: DateRangeControl` - The date range picker instance
970
+ - `getDisplayValue(): string` - Get current display value from input
971
+ - `getDates(): DateRangeResult` - Get current date range data
972
+ - `setDates(startISO: string, endISO: string): void` - Set date range programmatically
973
+ - `setHelperText(text: string, type?: 'default' | 'success' | 'error'): void` - Update helper text
974
+ - `destroy(): void` - Clean up and remove all created elements
975
+
976
+ **Key Features:**
977
+ - **Automatic HTML Creation**: Creates complete styled input structure inside target DIV
978
+ - **Premium MyIO Styling**: Beautiful styling matching demos/energy.html with purple brand colors
979
+ - **Container-Based**: Works with any DIV container, perfect for ThingsBoard widgets
980
+ - **Accessibility Built-in**: ARIA labels, keyboard navigation, screen reader support
981
+ - **Responsive Design**: Mobile-friendly with proper touch targets
982
+ - **Error Handling**: Robust validation and graceful error recovery
983
+ - **Memory Management**: Proper cleanup with destroy() method
984
+
985
+ **Usage Example:**
986
+ ```javascript
987
+ import { createInputDateRangePickerInsideDIV } from 'myio-js-library';
988
+
989
+ const controller = await createInputDateRangePickerInsideDIV({
990
+ containerId: 'date-picker-container',
991
+ inputId: 'energy-date-range',
992
+ label: 'Período de Análise',
993
+ pickerOptions: {
994
+ presetStart: '2025-09-01',
995
+ presetEnd: '2025-09-25',
996
+ onApply: (result) => {
997
+ console.log('Date range selected:', result);
998
+ // result.startISO: "2025-09-01T00:00:00-03:00"
999
+ // result.endISO: "2025-09-25T23:59:59-03:00"
1000
+ loadEnergyData(result.startISO, result.endISO);
1001
+ }
1002
+ }
1003
+ });
1004
+
1005
+ // Get current selection
1006
+ const dates = controller.getDates();
1007
+ console.log('Current range:', dates.startISO, 'to', dates.endISO);
1008
+
1009
+ // Update helper text
1010
+ controller.setHelperText('Período válido selecionado', 'success');
1011
+
1012
+ // Clean up when done
1013
+ controller.destroy();
1014
+ ```
1015
+
1016
+ **ThingsBoard Widget Integration:**
1017
+ ```html
1018
+ <script src="https://unpkg.com/myio-js-library@latest/dist/myio-js-library.umd.min.js"></script>
1019
+ <script>
1020
+ const { createInputDateRangePickerInsideDIV } = MyIOLibrary;
1021
+
1022
+ // In your widget's onInit function
1023
+ self.onInit = async function() {
1024
+ try {
1025
+ // Create date range picker in existing container
1026
+ self.dateRangePicker = await createInputDateRangePickerInsideDIV({
1027
+ containerId: 'widget-date-container',
1028
+ inputId: 'energy-widget-dates',
1029
+ label: 'Período de Datas',
1030
+ placeholder: 'Selecione o período de análise',
1031
+ pickerOptions: {
1032
+ maxRangeDays: 31,
1033
+ onApply: (result) => {
1034
+ // Update widget state and reload data
1035
+ updateWidgetData(result.startISO, result.endISO);
1036
+ }
1037
+ }
1038
+ });
1039
+
1040
+ console.log('[ENERGY] Date range picker initialized successfully');
1041
+ } catch (error) {
1042
+ console.error('[ENERGY] Failed to initialize date picker:', error);
1043
+ // Fallback to legacy implementation
1044
+ initLegacyDatePicker();
1045
+ }
1046
+ };
1047
+
1048
+ // Clean up on widget destroy
1049
+ self.onDestroy = function() {
1050
+ if (self.dateRangePicker) {
1051
+ self.dateRangePicker.destroy();
1052
+ }
1053
+ };
1054
+ </script>
1055
+ ```
1056
+
1057
+ **Premium Styling Features:**
1058
+ - **MyIO Brand Colors**: Purple theme (#4A148C) with hover effects
1059
+ - **Responsive Layout**: Adapts to mobile and desktop with proper spacing
1060
+ - **Accessibility**: High contrast mode support, reduced motion support
1061
+ - **Visual Feedback**: Hover states, focus indicators, success/error states
1062
+ - **Typography**: Roboto font family with proper line heights
1063
+ - **Shadow Effects**: Subtle shadows and smooth transitions
1064
+
1065
+ **Migration from Basic Implementation:**
1066
+ ```javascript
1067
+ // OLD: Manual HTML + basic styling
1068
+ var $inputStart = $('input[name="startDatetimes"]');
1069
+ MyIOLibrary.createDateRangePicker($inputStart[0], options);
1070
+
1071
+ // NEW: Automatic creation + premium styling
1072
+ const controller = await MyIOLibrary.createInputDateRangePickerInsideDIV({
1073
+ containerId: 'date-container',
1074
+ inputId: 'startDatetimes',
1075
+ label: 'Período de Datas',
1076
+ pickerOptions: options
1077
+ });
1078
+ ```
1079
+
1080
+ ### Premium Modal Components
1081
+
1082
+ The library includes four premium modal components for ThingsBoard dashboards that provide comprehensive device analytics and reporting capabilities.
1083
+
1084
+ #### `openDashboardPopupReport(params: OpenDeviceReportParams): ModalHandle`
1085
+
1086
+ Opens a device-specific daily consumption report modal with built-in date range picker, sortable table, and CSV export functionality.
1087
+
1088
+ **Parameters:**
1089
+ - `ingestionId: string` - Data ingestion identifier (required)
1090
+ - `deviceId?: string` - Optional device ID for additional metadata
1091
+ - `identifier?: string` - Device identifier/code (e.g., "ENTRADA-001", "CHILLER-A")
1092
+ - `label?: string` - Human-readable label/name (e.g., "Outback", "Shopping Center Norte")
1093
+ - `ui?: object` - UI configuration (theme, width)
1094
+ - `api: object` - API configuration:
1095
+ - `clientId?: string` - Client ID for data API
1096
+ - `clientSecret?: string` - Client secret for data API
1097
+ - `dataApiBaseUrl?: string` - Data API base URL
1098
+ - `ingestionToken?: string` - Token for data ingestion access
1099
+
1100
+ **Returns:** `ModalHandle` object with:
1101
+ - `close(): void` - Close the modal
1102
+ - `on(event: 'close'|'loaded'|'error', handler: Function): void` - Event listeners
1103
+
1104
+ **Key Features:**
1105
+ - **Built-in Date Range Picker**: No need to specify dates in parameters
1106
+ - **Automatic Data Loading**: Fetches daily consumption data for selected period
1107
+ - **Sortable Table**: Click column headers to sort by date or consumption
1108
+ - **CSV Export**: Download report data with proper Brazilian formatting
1109
+ - **Responsive Design**: Works on desktop and mobile devices
1110
+ - **Error Handling**: Graceful error display and recovery
1111
+
1112
+ **Usage Example:**
1113
+ ```javascript
1114
+ import { openDashboardPopupReport } from 'myio-js-library';
1115
+
1116
+ const modal = openDashboardPopupReport({
1117
+ ingestionId: 'abc123-ingestion-id',
1118
+ deviceId: 'device-uuid',
1119
+ identifier: 'ENTRADA-001',
1120
+ label: 'Outback Shopping',
1121
+ api: {
1122
+ clientId: 'your-client-id',
1123
+ clientSecret: 'your-client-secret',
1124
+ dataApiBaseUrl: 'https://api.data.apps.myio-bas.com',
1125
+ ingestionToken: 'your-ingestion-token'
1126
+ }
1127
+ });
1128
+
1129
+ modal.on('loaded', (data) => {
1130
+ console.log('Report loaded:', data.count, 'days');
1131
+ });
1132
+
1133
+ modal.on('close', () => {
1134
+ console.log('Modal closed');
1135
+ });
1136
+ ```
1137
+
1138
+ #### `openDashboardPopupAllReport(params: OpenAllReportParams): ModalHandle`
1139
+
1140
+ Opens a customer-level energy consumption report modal with real-time data from the Customer Totals API. This modal provides comprehensive reporting across all devices for a customer with advanced sorting, filtering, and export capabilities.
1141
+
1142
+ **Parameters:**
1143
+ - `customerId: string` - ThingsBoard customer ID (required)
1144
+ - `ui?: object` - UI configuration (theme, width)
1145
+ - `api: object` - API configuration:
1146
+ - `clientId?: string` - Client ID for data API authentication
1147
+ - `clientSecret?: string` - Client secret for data API authentication
1148
+ - `dataApiBaseUrl?: string` - Data API base URL (default: 'https://api.data.apps.myio-bas.com')
1149
+ - `filters?: object` - Optional filtering configuration:
1150
+ - `excludeLabels?: (RegExp | string)[]` - Patterns to exclude devices by label
1151
+ - `fetcher?: Function` - Optional custom fetcher for testing/mocking
1152
+
1153
+ **Returns:** `ModalHandle` object with:
1154
+ - `close(): void` - Close the modal
1155
+ - `on(event: 'close'|'loaded'|'error', handler: Function): void` - Event listeners
1156
+
1157
+ **Key Features:**
1158
+ - **Real Customer Totals API Integration**: Calls `/api/v1/telemetry/customers/{customerId}/energy/devices/totals`
1159
+ - **Built-in Date Range Picker**: Interactive date selection with validation
1160
+ - **Robust Data Processing**: Handles pagination, fallback chains, and data normalization
1161
+ - **Sortable Table Structure**: Sticky totals row + sortable columns (Identifier, Name, Consumption)
1162
+ - **Portuguese Locale Support**: Brazilian number formatting and sorting
1163
+ - **Comprehensive Error Handling**: Network failures, authentication, and validation errors
1164
+ - **CSV Export**: Consistent formatting with UI using `MyIOLibrary.formatEnergy`
1165
+ - **Production Ready**: Authentication via `fetchWithAuth` pattern with automatic token refresh
1166
+
1167
+ **Usage Example:**
1168
+ ```javascript
1169
+ import { openDashboardPopupAllReport } from 'myio-js-library';
1170
+
1171
+ const modal = openDashboardPopupAllReport({
1172
+ customerId: '73d4c75d-c311-4e98-a852-10a2231007c4',
1173
+ api: {
1174
+ clientId: 'your-client-id',
1175
+ clientSecret: 'your-client-secret',
1176
+ dataApiBaseUrl: 'https://api.data.apps.myio-bas.com'
1177
+ },
1178
+ filters: {
1179
+ excludeLabels: [
1180
+ /bomba.*secund[aá]ria/i, // Regex patterns
1181
+ /^administra[cç][aã]o\s*1$/i,
1182
+ 'Entrada Principal' // Exact string matches
1183
+ ]
1184
+ }
1185
+ });
1186
+
1187
+ modal.on('loaded', (data) => {
1188
+ console.log('Customer report loaded:', data.count, 'devices');
1189
+ console.log('Total consumption:', data.totalKwh, 'kWh');
1190
+ });
1191
+
1192
+ modal.on('error', (error) => {
1193
+ console.error('Report error:', error.message);
1194
+ });
1195
+ ```
1196
+
1197
+ **UMD Usage (ThingsBoard widgets):**
1198
+ ```html
1199
+ <script src="https://unpkg.com/myio-js-library@latest/dist/myio-js-library.umd.min.js"></script>
1200
+ <script>
1201
+ const { openDashboardPopupAllReport } = MyIOLibrary;
1202
+
1203
+ const modal = openDashboardPopupAllReport({
1204
+ customerId: 'your-customer-id',
1205
+ api: {
1206
+ clientId: 'your-client-id',
1207
+ clientSecret: 'your-client-secret'
1208
+ }
1209
+ });
1210
+
1211
+ modal.on('loaded', (data) => {
1212
+ console.log('All stores report loaded with', data.count, 'devices');
1213
+ console.log('Grand total:', data.totalKwh, 'kWh');
1214
+ });
1215
+ </script>
1216
+ ```
1217
+
1218
+ **Data Flow:**
1219
+ ```
1220
+ User clicks "Carregar"
1221
+ → Format timestamps with timezone offset
1222
+ → Call Customer Totals API with fetchWithAuth
1223
+ → Process response with mapCustomerTotalsResponse
1224
+ → Apply sorting with applySorting (Portuguese locale)
1225
+ → Update table with updateAllReportTable
1226
+ → Update totals with updateGrandTotal
1227
+ → Enable CSV export with habilitarBotaoExportAll
1228
+ ```
1229
+
1230
+ **API Integration:**
1231
+ ```
1232
+ GET ${DATA_API_HOST}/api/v1/telemetry/customers/{customerId}/energy/devices/totals
1233
+ ?startTime=2025-09-01T00%3A00%3A00-03%3A00
1234
+ &endTime=2025-09-25T23%3A59%3A59-03%3A00
1235
+
1236
+ Authorization: Bearer ${MyIOAuth.getToken()}
1237
+ ```
1238
+
1239
+ **Migration from Legacy Implementation:**
1240
+ ```javascript
1241
+ // OLD: Mock/placeholder data
1242
+ MyIOLibrary.openDashboardPopupAllReport({
1243
+ // Used mock data or device-by-device calls
1244
+ });
1245
+
1246
+ // NEW: Real Customer Totals API
1247
+ MyIOLibrary.openDashboardPopupAllReport({
1248
+ customerId: 'your-customer-id', // ✅ Real customer ID
1249
+ api: {
1250
+ clientId: 'your-client-id', // ✅ Real API credentials
1251
+ clientSecret: 'your-client-secret'
1252
+ }
1253
+ // ✅ Calls real Customer Totals API endpoint
1254
+ // ✅ Handles pagination automatically
1255
+ // ✅ Robust error handling and recovery
1256
+ });
1257
+ ```
1258
+
1259
+ **UMD Usage (ThingsBoard widgets):**
1260
+ ```html
1261
+ <script src="https://unpkg.com/myio-js-library@latest/dist/myio-js-library.umd.min.js"></script>
1262
+ <script>
1263
+ const { openDashboardPopupReport } = MyIOLibrary;
1264
+
1265
+ const modal = openDashboardPopupReport({
1266
+ ingestionId: 'demo-ingestion-123',
1267
+ deviceId: 'demo-device-123',
1268
+ identifier: 'ENTRADA-001',
1269
+ label: 'Outback',
1270
+ api: {
1271
+ clientId: 'demo-client',
1272
+ clientSecret: 'demo-secret',
1273
+ dataApiBaseUrl: 'https://api.data.apps.myio-bas.com',
1274
+ ingestionToken: 'demo-ingestion-token'
1275
+ }
1276
+ });
1277
+
1278
+ modal.on('loaded', (data) => {
1279
+ console.log('Device report loaded with', data.count, 'days of data');
1280
+ });
1281
+ </script>
1282
+ ```
1283
+
1284
+ **Migration from Legacy API:**
1285
+ ```javascript
1286
+ // OLD API (deprecated)
1287
+ MyIOLibrary.openDashboardPopupReport({
1288
+ ingestionId: 'demo-ingestion-123',
1289
+ deviceLabel: 'Entrada Subestação', // ❌ Deprecated
1290
+ storeLabel: 'Outback', // ❌ Deprecated
1291
+ date: { start: '2025-09-01', end: '2025-09-25' }, // ❌ Deprecated
1292
+ api: { tbJwtToken: 'jwt-token' } // ❌ Deprecated
1293
+ });
1294
+
1295
+ // NEW API (recommended)
1296
+ MyIOLibrary.openDashboardPopupReport({
1297
+ ingestionId: 'demo-ingestion-123',
1298
+ identifier: 'ENTRADA-001', // ✅ Clear device identifier
1299
+ label: 'Outback', // ✅ Clear human-readable name
1300
+ api: { ingestionToken: 'ingestion-token' } // ✅ Clear token purpose
1301
+ });
1302
+ ```
1303
+
948
1304
  ### MYIO Components - Drag-to-Footer Dock Implementation
949
1305
 
950
1306
  The library includes three main interactive components for building comparative selection interfaces: