config-editor-base 2.9.4 → 2.9.6

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
@@ -145,7 +145,86 @@ The config editor also supports various S3 calls, e.g. for loading Rule Schema a
145
145
 
146
146
  The config editor relies on styling from the parent application. For examples of styling, see the CANedge configuration editor.
147
147
 
148
- ---
148
+ ---
149
+
150
+ ## Editor Base Tools
151
+
152
+ The module includes built-in tools for OBD configuration and filter building. These are exported as `OBDTool` and `FilterBuilderTool`.
153
+
154
+ ### OBD Tool
155
+
156
+ Generates OBD-II transmit lists for CANedge devices. Key features:
157
+ - **PID Selection**: Select standard OBD-II PIDs from a built-in database
158
+ - **Supported PIDs Parser**: Parse response data to identify vehicle-supported PIDs
159
+ - **Control Signal**: Optional GPS-based speed control signal to prevent battery drain when vehicle is off
160
+ - **Transmit List Generation**: Outputs partial JSON for merging with device configuration
161
+
162
+ ```jsx
163
+ import { OBDTool } from "config-editor-base";
164
+
165
+ // In editorTools array:
166
+ {
167
+ name: "obd-modal",
168
+ comment: "OBD tool",
169
+ class: "fa fa-car",
170
+ modal: <OBDTool showAlert={this.props.showAlert} />
171
+ }
172
+ ```
173
+
174
+ ### Filter Builder Tool
175
+
176
+ Analyzes CSV log files to help users create optimized CAN filters. Key features:
177
+ - **CSV Analysis**: Load mdf2csv output to see CAN ID distribution by size contribution
178
+ - **DBC Matching**: Match CAN IDs to DBC message names and signals
179
+ - **J1939 PGN Grouping**: Group 29-bit IDs by PGN for J1939/ISOBUS protocols
180
+ - **Filter Generation**: Generate acceptance filters with optional prescalers
181
+ - **Reset Filters**: Reset CAN channel filters to defaults (record everything)
182
+
183
+ ```jsx
184
+ import { FilterBuilderTool } from "config-editor-base";
185
+
186
+ // In editorTools array:
187
+ {
188
+ name: "filter-builder-modal",
189
+ comment: "Filter builder",
190
+ class: "fa fa-sliders",
191
+ modal: <FilterBuilderTool showAlert={this.props.showAlert} deviceType="CANedge" />
192
+ }
193
+ ```
194
+
195
+ The `deviceType` prop controls device-specific behavior:
196
+ - `"CANedge"` or `"CANedge2 GNSS"`: Standard CANedge filter structure
197
+ - `"CANmod"`: CANmod.router filter structure (requires `frame_format` field)
198
+
199
+ ### Updating for New Firmware Revisions
200
+
201
+ When a new firmware revision is released (e.g., CANedge 01.10.XX), update these files:
202
+
203
+ #### 1. Supported Firmware Versions (`FilterBuilderTool.js`)
204
+ ```javascript
205
+ // Add new version to the supported arrays at top of file:
206
+ const SUPPORTED_FIRMWARE_CANEDGE = ["01.08", "01.09", "01.10"]; // Add here
207
+ const SUPPORTED_FIRMWARE_CANMOD_ROUTER = ["01.02"];
208
+ ```
209
+
210
+ #### 2. Default Filter Configs (`src/editorBaseTools/filterBuilder/`)
211
+ If the filter schema changes, create new default filter JSON files:
212
+ - `canedge-default-filters-XX.YY.json`
213
+ - `canedge-default-filters-gps-XX.YY.json`
214
+ - `canmod-router-default-filters-XX.YY.json`
215
+
216
+ Then update imports in `FilterBuilderTool.js` if structure changes.
217
+
218
+ #### 3. Control Signal Config (`src/editorBaseTools/obd/`)
219
+ If the control signal schema changes:
220
+ - Create `control-signal-internal-gps-XX.YY.json`
221
+ - Update import in `OBDTool.js`
222
+
223
+ #### 4. Schema Files (`dist/schema/`)
224
+ Add new schema and uischema files to the appropriate folders and update `schemaAry`/`uiSchemaAry` in `Editor.js`.
225
+
226
+ ---
227
+
149
228
  ## Regarding JSON Schema files
150
229
 
151
230
  The module expects to find JSON Schema files in the structure below to facilitate auto-loading of these:
package/dist/index.js CHANGED
@@ -22309,7 +22309,8 @@ var OBDTool = /*#__PURE__*/function (_React$Component) {
22309
22309
  _proto.onMerge = function onMerge() {
22310
22310
  var _this$state5 = this.state,
22311
22311
  combinedConfig = _this$state5.combinedConfig,
22312
- mergedConfigValid = _this$state5.mergedConfigValid;
22312
+ mergedConfigValid = _this$state5.mergedConfigValid,
22313
+ enableControlSignal = _this$state5.enableControlSignal;
22313
22314
  var formData = this.props.formData;
22314
22315
  if (mergedConfigValid !== true) {
22315
22316
  this.props.showAlert("warning", "Cannot merge - the combined configuration is invalid. Check console for details.");
@@ -22327,10 +22328,19 @@ var OBDTool = /*#__PURE__*/function (_React$Component) {
22327
22328
  });
22328
22329
  this.props.setConfigContent(freshMergedConfig);
22329
22330
  this.props.setUpdatedFormData(freshMergedConfig);
22330
- this.props.showAlert("success", "Merged OBD transmit list with Configuration File");
22331
+ if (!enableControlSignal) {
22332
+ this.props.showAlert("warning", "Merged OBD transmit list with Configuration File. Important: If your CANedge transmits data while the vehicle ignition is off it can drain the vehicle battery. Use a control signal to start/stop transmission or ensure the device powers off with the ignition (e.g. by changing the installation setup or manually disconnecting the device).");
22333
+ } else {
22334
+ this.props.showAlert("success", "Merged OBD transmit list with Configuration File");
22335
+ }
22331
22336
  };
22332
22337
  _proto.onDownload = function onDownload() {
22333
- var generatedConfig = this.state.generatedConfig;
22338
+ var _this$state6 = this.state,
22339
+ generatedConfig = _this$state6.generatedConfig,
22340
+ enableControlSignal = _this$state6.enableControlSignal;
22341
+ if (!enableControlSignal) {
22342
+ this.props.showAlert("warning", "Important: If your CANedge transmits data while the vehicle ignition is off it can drain the vehicle battery. Use a control signal to start/stop transmission or ensure the device powers off with the ignition (e.g. by changing the installation setup or manually disconnecting the device).");
22343
+ }
22334
22344
  var dataStr = JSON.stringify(generatedConfig, null, 2);
22335
22345
  var dataUri = 'data:application/json;charset=utf-8,' + encodeURIComponent(dataStr);
22336
22346
  var exportFileDefaultName = 'obd-transmit-list.json';
@@ -22341,23 +22351,23 @@ var OBDTool = /*#__PURE__*/function (_React$Component) {
22341
22351
  };
22342
22352
  _proto.render = function render() {
22343
22353
  var _this9 = this;
22344
- var _this$state6 = this.state,
22345
- toolMode = _this$state6.toolMode,
22346
- channel = _this$state6.channel,
22347
- bitRate = _this$state6.bitRate,
22348
- canId = _this$state6.canId,
22349
- obdMode = _this$state6.obdMode,
22350
- spacing = _this$state6.spacing,
22351
- searchQuery = _this$state6.searchQuery,
22352
- supportedPids = _this$state6.supportedPids,
22353
- generatedConfig = _this$state6.generatedConfig,
22354
- mergedConfigValid = _this$state6.mergedConfigValid,
22355
- csvFileName = _this$state6.csvFileName,
22356
- mixedWarning = _this$state6.mixedWarning,
22357
- showPreview = _this$state6.showPreview,
22358
- enableControlSignal = _this$state6.enableControlSignal,
22359
- enableOBDFilter = _this$state6.enableOBDFilter,
22360
- combinedConfig = _this$state6.combinedConfig;
22354
+ var _this$state7 = this.state,
22355
+ toolMode = _this$state7.toolMode,
22356
+ channel = _this$state7.channel,
22357
+ bitRate = _this$state7.bitRate,
22358
+ canId = _this$state7.canId,
22359
+ obdMode = _this$state7.obdMode,
22360
+ spacing = _this$state7.spacing,
22361
+ searchQuery = _this$state7.searchQuery,
22362
+ supportedPids = _this$state7.supportedPids,
22363
+ generatedConfig = _this$state7.generatedConfig,
22364
+ mergedConfigValid = _this$state7.mergedConfigValid,
22365
+ csvFileName = _this$state7.csvFileName,
22366
+ mixedWarning = _this$state7.mixedWarning,
22367
+ showPreview = _this$state7.showPreview,
22368
+ enableControlSignal = _this$state7.enableControlSignal,
22369
+ enableOBDFilter = _this$state7.enableOBDFilter,
22370
+ combinedConfig = _this$state7.combinedConfig;
22361
22371
  var _this$props = this.props,
22362
22372
  formData = _this$props.formData,
22363
22373
  editorConfigFiles = _this$props.editorConfigFiles;
@@ -23120,6 +23130,392 @@ function evaluateFilters(frames, configData, detectedDeviceType) {
23120
23130
  };
23121
23131
  }
23122
23132
 
23133
+ var can_internal$1 = {
23134
+ filter: {
23135
+ id: [
23136
+ {
23137
+ name: "Heartbeat",
23138
+ state: 0,
23139
+ type: 0,
23140
+ id_format: 0,
23141
+ method: 0,
23142
+ f1: "2",
23143
+ f2: "2",
23144
+ prescaler_type: 0
23145
+ },
23146
+ {
23147
+ name: "TimeCalendar",
23148
+ state: 0,
23149
+ type: 0,
23150
+ id_format: 0,
23151
+ method: 0,
23152
+ f1: "3",
23153
+ f2: "3",
23154
+ prescaler_type: 0
23155
+ },
23156
+ {
23157
+ name: "TimeExternal",
23158
+ state: 0,
23159
+ type: 0,
23160
+ id_format: 0,
23161
+ method: 0,
23162
+ f1: "5",
23163
+ f2: "5",
23164
+ prescaler_type: 0
23165
+ }
23166
+ ]
23167
+ }
23168
+ };
23169
+ var can_1$2 = {
23170
+ filter: {
23171
+ remote_frames: 0,
23172
+ id: [
23173
+ {
23174
+ name: "AllStandardID",
23175
+ state: 1,
23176
+ type: 0,
23177
+ id_format: 0,
23178
+ method: 0,
23179
+ f1: "0",
23180
+ f2: "7FF",
23181
+ prescaler_type: 0
23182
+ },
23183
+ {
23184
+ name: "AllExtendedID",
23185
+ state: 1,
23186
+ type: 0,
23187
+ id_format: 1,
23188
+ method: 0,
23189
+ f1: "0",
23190
+ f2: "1FFFFFFF",
23191
+ prescaler_type: 0
23192
+ }
23193
+ ]
23194
+ }
23195
+ };
23196
+ var can_2$1 = {
23197
+ filter: {
23198
+ remote_frames: 0,
23199
+ id: [
23200
+ {
23201
+ name: "AllStandardID",
23202
+ state: 1,
23203
+ type: 0,
23204
+ id_format: 0,
23205
+ method: 0,
23206
+ f1: "0",
23207
+ f2: "7FF",
23208
+ prescaler_type: 0
23209
+ },
23210
+ {
23211
+ name: "AllExtendedID",
23212
+ state: 1,
23213
+ type: 0,
23214
+ id_format: 1,
23215
+ method: 0,
23216
+ f1: "0",
23217
+ f2: "1FFFFFFF",
23218
+ prescaler_type: 0
23219
+ }
23220
+ ]
23221
+ }
23222
+ };
23223
+ var canedgeDefaultFilters = {
23224
+ can_internal: can_internal$1,
23225
+ can_1: can_1$2,
23226
+ can_2: can_2$1
23227
+ };
23228
+
23229
+ var can_internal$2 = {
23230
+ filter: {
23231
+ id: [
23232
+ {
23233
+ name: "Heartbeat",
23234
+ state: 0,
23235
+ type: 0,
23236
+ id_format: 0,
23237
+ method: 0,
23238
+ f1: "2",
23239
+ f2: "2",
23240
+ prescaler_type: 0
23241
+ },
23242
+ {
23243
+ name: "TimeCalendar",
23244
+ state: 0,
23245
+ type: 0,
23246
+ id_format: 0,
23247
+ method: 0,
23248
+ f1: "3",
23249
+ f2: "3",
23250
+ prescaler_type: 0
23251
+ },
23252
+ {
23253
+ name: "TimeExternal",
23254
+ state: 0,
23255
+ type: 0,
23256
+ id_format: 0,
23257
+ method: 0,
23258
+ f1: "5",
23259
+ f2: "5",
23260
+ prescaler_type: 0
23261
+ },
23262
+ {
23263
+ name: "GnssStatus",
23264
+ state: 1,
23265
+ type: 0,
23266
+ id_format: 0,
23267
+ method: 0,
23268
+ f1: "65",
23269
+ f2: "65",
23270
+ prescaler_type: 0
23271
+ },
23272
+ {
23273
+ name: "GnssTime",
23274
+ state: 1,
23275
+ type: 0,
23276
+ id_format: 0,
23277
+ method: 0,
23278
+ f1: "66",
23279
+ f2: "66",
23280
+ prescaler_type: 0
23281
+ },
23282
+ {
23283
+ name: "GnsssPosition",
23284
+ state: 1,
23285
+ type: 0,
23286
+ id_format: 0,
23287
+ method: 0,
23288
+ f1: "67",
23289
+ f2: "67",
23290
+ prescaler_type: 0
23291
+ },
23292
+ {
23293
+ name: "GnssAltitude",
23294
+ state: 1,
23295
+ type: 0,
23296
+ id_format: 0,
23297
+ method: 0,
23298
+ f1: "68",
23299
+ f2: "68",
23300
+ prescaler_type: 0
23301
+ },
23302
+ {
23303
+ name: "GnssAttitude",
23304
+ state: 1,
23305
+ type: 0,
23306
+ id_format: 0,
23307
+ method: 0,
23308
+ f1: "69",
23309
+ f2: "69",
23310
+ prescaler_type: 0
23311
+ },
23312
+ {
23313
+ name: "GnssDistance",
23314
+ state: 1,
23315
+ type: 0,
23316
+ id_format: 0,
23317
+ method: 0,
23318
+ f1: "6A",
23319
+ f2: "6A",
23320
+ prescaler_type: 0
23321
+ },
23322
+ {
23323
+ name: "GnssSpeed",
23324
+ state: 1,
23325
+ type: 0,
23326
+ id_format: 0,
23327
+ method: 0,
23328
+ f1: "6B",
23329
+ f2: "6B",
23330
+ prescaler_type: 0
23331
+ },
23332
+ {
23333
+ name: "GnssGeofence",
23334
+ state: 1,
23335
+ type: 0,
23336
+ id_format: 0,
23337
+ method: 0,
23338
+ f1: "6C",
23339
+ f2: "6C",
23340
+ prescaler_type: 0
23341
+ },
23342
+ {
23343
+ name: "ImuAlign",
23344
+ state: 1,
23345
+ type: 0,
23346
+ id_format: 0,
23347
+ method: 0,
23348
+ f1: "6E",
23349
+ f2: "6E",
23350
+ prescaler_type: 0
23351
+ },
23352
+ {
23353
+ name: "ImuAcc",
23354
+ state: 1,
23355
+ type: 0,
23356
+ id_format: 0,
23357
+ method: 0,
23358
+ f1: "6F",
23359
+ f2: "6F",
23360
+ prescaler_type: 0
23361
+ }
23362
+ ]
23363
+ }
23364
+ };
23365
+ var can_1$3 = {
23366
+ filter: {
23367
+ remote_frames: 0,
23368
+ id: [
23369
+ {
23370
+ name: "AllStandardID",
23371
+ state: 1,
23372
+ type: 0,
23373
+ id_format: 0,
23374
+ method: 0,
23375
+ f1: "0",
23376
+ f2: "7FF",
23377
+ prescaler_type: 0
23378
+ },
23379
+ {
23380
+ name: "AllExtendedID",
23381
+ state: 1,
23382
+ type: 0,
23383
+ id_format: 1,
23384
+ method: 0,
23385
+ f1: "0",
23386
+ f2: "1FFFFFFF",
23387
+ prescaler_type: 0
23388
+ }
23389
+ ]
23390
+ }
23391
+ };
23392
+ var can_2$2 = {
23393
+ filter: {
23394
+ remote_frames: 0,
23395
+ id: [
23396
+ {
23397
+ name: "AllStandardID",
23398
+ state: 1,
23399
+ type: 0,
23400
+ id_format: 0,
23401
+ method: 0,
23402
+ f1: "0",
23403
+ f2: "7FF",
23404
+ prescaler_type: 0
23405
+ },
23406
+ {
23407
+ name: "AllExtendedID",
23408
+ state: 1,
23409
+ type: 0,
23410
+ id_format: 1,
23411
+ method: 0,
23412
+ f1: "0",
23413
+ f2: "1FFFFFFF",
23414
+ prescaler_type: 0
23415
+ }
23416
+ ]
23417
+ }
23418
+ };
23419
+ var canedgeDefaultFiltersGps = {
23420
+ can_internal: can_internal$2,
23421
+ can_1: can_1$3,
23422
+ can_2: can_2$2
23423
+ };
23424
+
23425
+ var phy = {
23426
+ can_s1: {
23427
+ filter: [
23428
+ {
23429
+ name: "AllStandardID",
23430
+ state: 1,
23431
+ id_format: 0,
23432
+ frame_format: 2,
23433
+ f1: "7FF",
23434
+ f2: "0",
23435
+ prescaler_type: 0
23436
+ },
23437
+ {
23438
+ name: "AllExtendedID",
23439
+ state: 1,
23440
+ id_format: 1,
23441
+ frame_format: 2,
23442
+ f1: "1FFFFFFF",
23443
+ f2: "0",
23444
+ prescaler_type: 0
23445
+ }
23446
+ ]
23447
+ },
23448
+ can_s2: {
23449
+ filter: [
23450
+ {
23451
+ name: "AllStandardID",
23452
+ state: 1,
23453
+ id_format: 0,
23454
+ frame_format: 2,
23455
+ f1: "7FF",
23456
+ f2: "0",
23457
+ prescaler_type: 0
23458
+ },
23459
+ {
23460
+ name: "AllExtendedID",
23461
+ state: 1,
23462
+ id_format: 1,
23463
+ frame_format: 2,
23464
+ f1: "1FFFFFFF",
23465
+ f2: "0",
23466
+ prescaler_type: 0
23467
+ }
23468
+ ]
23469
+ },
23470
+ can_s3: {
23471
+ filter: [
23472
+ {
23473
+ name: "AllStandardID",
23474
+ state: 1,
23475
+ id_format: 0,
23476
+ frame_format: 2,
23477
+ f1: "7FF",
23478
+ f2: "0",
23479
+ prescaler_type: 0
23480
+ },
23481
+ {
23482
+ name: "AllExtendedID",
23483
+ state: 1,
23484
+ id_format: 1,
23485
+ frame_format: 2,
23486
+ f1: "1FFFFFFF",
23487
+ f2: "0",
23488
+ prescaler_type: 0
23489
+ }
23490
+ ]
23491
+ },
23492
+ can_s4: {
23493
+ filter: [
23494
+ {
23495
+ name: "AllStandardID",
23496
+ state: 1,
23497
+ id_format: 0,
23498
+ frame_format: 2,
23499
+ f1: "7FF",
23500
+ f2: "0",
23501
+ prescaler_type: 0
23502
+ },
23503
+ {
23504
+ name: "AllExtendedID",
23505
+ state: 1,
23506
+ id_format: 1,
23507
+ frame_format: 2,
23508
+ f1: "1FFFFFFF",
23509
+ f2: "0",
23510
+ prescaler_type: 0
23511
+ }
23512
+ ]
23513
+ }
23514
+ };
23515
+ var canmodRouterDefaultFilters = {
23516
+ phy: phy
23517
+ };
23518
+
23123
23519
  var _excluded = ["name"],
23124
23520
  _excluded2 = ["name"];
23125
23521
  var merge$2 = require("deepmerge");
@@ -23140,8 +23536,10 @@ var MAX_11BIT_FILTERS_CANEDGE = 128;
23140
23536
  var MAX_29BIT_FILTERS_CANEDGE = 64;
23141
23537
  var MAX_FILTERS_CANMOD_ROUTER = 32;
23142
23538
  var CANEDGE_CHANNELS = ["CAN1", "CAN2", "CAN9"];
23143
- var MIN_FIRMWARE_CANEDGE = "01.09";
23144
- var MIN_FIRMWARE_CANMOD_ROUTER = "01.02";
23539
+ var SUPPORTED_FIRMWARE_CANEDGE = ["01.08", "01.09"];
23540
+ var SUPPORTED_FIRMWARE_CANMOD_ROUTER = ["01.02"];
23541
+ var MIN_FIRMWARE_CANEDGE = SUPPORTED_FIRMWARE_CANEDGE[0];
23542
+ var MIN_FIRMWARE_CANMOD_ROUTER = SUPPORTED_FIRMWARE_CANMOD_ROUTER[0];
23145
23543
  var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23146
23544
  function FilterBuilderTool(props) {
23147
23545
  var _this;
@@ -23159,6 +23557,7 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23159
23557
  _this.testMergedFile = _this.testMergedFile.bind(_this);
23160
23558
  _this.onMerge = _this.onMerge.bind(_this);
23161
23559
  _this.onDownload = _this.onDownload.bind(_this);
23560
+ _this.onReset = _this.onReset.bind(_this);
23162
23561
  _this.onSubmit = _this.onSubmit.bind(_this);
23163
23562
  _this.onValidationError = _this.onValidationError.bind(_this);
23164
23563
  _this.state = {
@@ -23248,9 +23647,9 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
23248
23647
  var version = this.getConfigVersion();
23249
23648
  if (!version) return false;
23250
23649
  if (this.props.deviceType === "CANmod") {
23251
- return version >= MIN_FIRMWARE_CANMOD_ROUTER;
23650
+ return SUPPORTED_FIRMWARE_CANMOD_ROUTER.includes(version);
23252
23651
  }
23253
- return version >= MIN_FIRMWARE_CANEDGE;
23652
+ return SUPPORTED_FIRMWARE_CANEDGE.includes(version);
23254
23653
  };
23255
23654
  _proto.calculateFrameWeight = function calculateFrameWeight(dataLength) {
23256
23655
  var baseWeight = 4;
@@ -24312,6 +24711,33 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24312
24711
  linkElement.setAttribute('download', exportFileDefaultName);
24313
24712
  linkElement.click();
24314
24713
  };
24714
+ _proto.onReset = function onReset() {
24715
+ var _this$props = this.props,
24716
+ formData = _this$props.formData,
24717
+ deviceType = _this$props.deviceType;
24718
+ if (!formData || Object.keys(formData).length === 0) {
24719
+ this.props.showAlert("warning", "No configuration file loaded");
24720
+ return;
24721
+ }
24722
+ var defaultFilters;
24723
+ var isCanmodRouter = this.isCanmodRouter();
24724
+ if (deviceType === "CANmod" && isCanmodRouter) {
24725
+ defaultFilters = canmodRouterDefaultFilters;
24726
+ } else if (deviceType && deviceType.includes("GNSS")) {
24727
+ defaultFilters = canedgeDefaultFiltersGps;
24728
+ } else {
24729
+ defaultFilters = canedgeDefaultFilters;
24730
+ }
24731
+ var overwriteMerge = function overwriteMerge(destinationArray, sourceArray, options) {
24732
+ return sourceArray;
24733
+ };
24734
+ var resetConfig = merge$2(formData, defaultFilters, {
24735
+ arrayMerge: overwriteMerge
24736
+ });
24737
+ this.props.setConfigContent(resetConfig);
24738
+ this.props.setUpdatedFormData(resetConfig);
24739
+ this.props.showAlert("success", "CAN channel filters reset to defaults (record everything)");
24740
+ };
24315
24741
  _proto.renderBarChart = function renderBarChart(percentage, maxPercentage) {
24316
24742
  var maxWidth = 25;
24317
24743
  var barWidth = Math.max(1, percentage / maxPercentage * maxWidth);
@@ -24357,7 +24783,7 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24357
24783
  style: {
24358
24784
  display: "flex",
24359
24785
  gap: "10px",
24360
- alignItems: "flex-start",
24786
+ alignItems: "center",
24361
24787
  flexWrap: "wrap"
24362
24788
  }
24363
24789
  }, /*#__PURE__*/React.createElement("div", {
@@ -24388,9 +24814,25 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24388
24814
  clickable: true
24389
24815
  }, /*#__PURE__*/React.createElement("button", {
24390
24816
  className: "btn btn-primary"
24391
- }, "Load DBC(s)")))), /*#__PURE__*/React.createElement("p", {
24817
+ }, "Load DBC(s)"))), function () {
24818
+ var isFirmwareSupported = _this12.isFirmwareVersionSupported();
24819
+ var isCanmod = _this12.props.deviceType === "CANmod";
24820
+ var isCanmodRouter = isCanmod && _this12.isCanmodRouter();
24821
+ var isDeviceSupported = !isCanmod || isCanmodRouter;
24822
+ var hasConfig = _this12.props.formData && Object.keys(_this12.props.formData).length > 0;
24823
+ return /*#__PURE__*/React.createElement("button", {
24824
+ className: "btn",
24825
+ onClick: _this12.onReset,
24826
+ disabled: !hasConfig || !isFirmwareSupported || !isDeviceSupported,
24827
+ style: {
24828
+ backgroundColor: "#fff",
24829
+ border: "1px solid #ccc",
24830
+ color: "#333"
24831
+ }
24832
+ }, "Reset filters");
24833
+ }()), /*#__PURE__*/React.createElement("span", {
24392
24834
  className: "field-description field-description-shift"
24393
- }, this.props.deviceType === "CANmod" ? "Load a CSV log file output from the MF4 converter 'mdf2csv' which reflects a realistic log session with the default filters applied. The MF4 should be recorded with a CANedge with one or two CANmod.router(s) on CAN2. The CSV should be created by first demuxing the MF4 via the 'mdf2mdf' converter using the argument '--muxtp-can2=010#11:12:13:14'. If you are analyzing a second router, use --muxtp-can2=012#15:16:17:18. Recommended CSV file size is 1-10 MB. Optionally load DBC file(s) to add further details or enable filter selection based on DBC messages. DBC files must have a CAN channel prefix (e.g. can11-abc.dbc)." : "Load a CSV log file output from the MF4 converter 'mdf2csv' which reflects a realistic log session with the default filters applied. Recommended CSV file size is 1-10 MB. Optionally load DBC file(s) to add further details or enable filter selection based on DBC messages. DBC files must have a CAN channel prefix (e.g. can1-abc.dbc)."), (csvFileName || dbcFileNames.length > 0) && /*#__PURE__*/React.createElement("div", {
24835
+ }, this.props.deviceType === "CANmod" ? "Load CSV: Load a log file recorded with CANedge + CANmod.router(s), demuxed via 'mdf2mdf' and converted to CSV via 'mdf2csv'. Load DBC(s): Add DBC files with channel prefix (e.g. can11-abc.dbc). Reset filters: Reset all CAN channel filters to defaults (record everything)." : "Load CSV: Load a CSV from 'mdf2csv' reflecting a realistic log session. Load DBC(s): Add DBC files with channel prefix (e.g. can1-abc.dbc). Reset filters: Reset all CAN channel filters to defaults (record everything)."), (csvFileName || dbcFileNames.length > 0) && /*#__PURE__*/React.createElement("div", {
24394
24836
  style: {
24395
24837
  fontSize: "11px",
24396
24838
  color: "#666",
@@ -24943,13 +25385,16 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
24943
25385
  }), /*#__PURE__*/React.createElement("span", {
24944
25386
  className: "field-description field-description-shift"
24945
25387
  }, _this12.state.prescalerType === "count" && "Accept every Nth message (1-256)", _this12.state.prescalerType === "time" && "Minimum time between messages (1-4194304 ms)", _this12.state.prescalerType === "data" && "Hex mask for data change detection")), /*#__PURE__*/React.createElement("div", {
25388
+ className: "form-group pl0 field-string",
25389
+ style: {
25390
+ marginBottom: "10px"
25391
+ }
25392
+ }, /*#__PURE__*/React.createElement("div", {
24946
25393
  style: {
24947
25394
  display: "flex",
24948
25395
  alignItems: "center",
24949
- marginBottom: "15px",
24950
25396
  gap: "10px"
24951
- },
24952
- title: "The new filters can either replace existing filters on the affected channel(s) or be appended at the top/bottom of the existing filters."
25397
+ }
24953
25398
  }, /*#__PURE__*/React.createElement("label", {
24954
25399
  style: {
24955
25400
  display: "flex",
@@ -25034,7 +25479,9 @@ var FilterBuilderTool = /*#__PURE__*/function (_React$Component) {
25034
25479
  position: "relative",
25035
25480
  top: "1px"
25036
25481
  }
25037
- }, "Append (bottom)"))), /*#__PURE__*/React.createElement("div", {
25482
+ }, "Append (bottom)"))), /*#__PURE__*/React.createElement("span", {
25483
+ className: "field-description field-description-shift"
25484
+ }, "The new filters can either replace existing filters on the affected channel(s) or be appended at the top/bottom of the existing filters. If you e.g. wish to prescale 5 specific IDs and then log everything else as-is, you can append the 5 ID filters at the top of the default filters.")), /*#__PURE__*/React.createElement("div", {
25038
25485
  style: {
25039
25486
  fontSize: "12px",
25040
25487
  color: "#666",