Improved: DateField locale formatting and picker behavior
DateField in @trackunit/react-form-components now displays, parses, and hints dates using the user's regional locale while continuing to emit canonical YYYY-MM-DD values to consumers.
Enhancements and updates to existing features
View All TagsDateField in @trackunit/react-form-components now displays, parses, and hints dates using the user's regional locale while continuing to emit canonical YYYY-MM-DD values to consumers.
The AEMP ISO Diagnostic Trouble Codes time-series endpoint now honors the Accept-Language request header when enriching fault codes with descriptions.
When an Accept-Language header is provided, the language is threaded through to the fault interpretation lookup, so the returned CodeDescription is localized to the caller's preferred language (for example, Accept-Language: da-DK,da;q=0.9,en;q=0.8 returns Danish descriptions) — but only if a translation for that language actually exists for the given fault code.
If no translation exists for the requested language — or if the header is omitted — the response falls back to the fault code's default description (typically English). The set of available languages depends on what the OEM provides and varies by manufacturer; common languages include English (en), German (de), French (fr), Italian (it), Spanish (es), Dutch (nl), Polish (pl), and Japanese (ja).
📝 GET:
/15143/-3/Fleet/Equipment/ID/{oemISOIdentifier}/Faults/{startDate}/{endDate}/{pageNumber}
Get diagnostic trouble codes time-series, with fault descriptions localized via the Accept-Language header.
useModal in @trackunit/react-modal has been updated with sheet mode support and container scoping. Modals can now automatically adapt to a sheet presentation when rendered inside a narrow container.
The WidgetKPI component now supports an onClick prop, making KPI cards interactive with a hover effect, chevron indicator, and keyboard accessibility.
WidgetContent padding has changed for KPI widgets using the onClick prop. If your widget previously used padding="responsive", you should update it to padding="none" — the WidgetKPI component now handles its own padding internally.
Iris Apps have been migrated from Rspack to Vite as the build system. Vite provides near-instant dev server startup, fast HMR using native ES modules, and optimized production builds.
Affected packages:
@trackunit/iris-app-sdk-rspack for build and serveOld executors removed:
Make sure you are on the latest Trackunit dependencies:
npx npm-check-updates "/@trackunit/" -u
Then install:
npm install
npm install @trackunit/iris-app-sdk-vite -D
project.jsonReplace the Rspack executors with the Vite equivalents.
Before:
{
"targets": {
"build": {
"executor": "@trackunit/iris-app-sdk-rspack:build",
"options": {
"rspackConfig": "apps/{app-name}/rspack.config.ts",
"outputPath": "dist/apps/{app-name}"
},
"outputs": ["{options.outputPath}"]
},
"serve": {
"executor": "@trackunit/iris-app-sdk-rspack:serve",
"options": {
"rspackConfig": "apps/{app-name}/rspack.config.ts"
}
}
}
}
After:
{
"targets": {
"build": {
"executor": "@trackunit/iris-app-sdk-vite:build",
"options": {
"outputPath": "dist/apps/{app-name}"
},
"outputs": ["{options.outputPath}"]
},
"serve": {
"executor": "@trackunit/iris-app-sdk-vite:serve",
"options": {}
}
}
}
Key changes:
@trackunit/iris-app-sdk-rspack to @trackunit/iris-app-sdk-viterspackConfig option is removed — Vite works with zero config by defaultviteConfig option if you need custom configuration (see Step 3)rspack.config.ts with vite.config.tsDelete your existing rspack.config.ts file.
If you had no customizations in your rspack config (i.e., it just returned the default configuration), you can skip creating a vite config entirely — it works out of the box.
If you need custom configuration, create a vite.config.ts in your app root:
import { defineConfig, UserConfig } from "vite";
export default defineConfig(async (configuration: UserConfig): Promise<UserConfig> => {
return configuration;
});
You can extend the default configuration by spreading and adding your overrides:
import { defineConfig, UserConfig } from "vite";
export default defineConfig(async (configuration: UserConfig): Promise<UserConfig> => {
return {
...configuration,
define: {
...configuration.define,
__MY_CUSTOM_FLAG__: JSON.stringify(true),
},
};
});
Then reference it in your project.json:
{
"serve": {
"executor": "@trackunit/iris-app-sdk-vite:serve",
"options": {
"viteConfig": "apps/{app-name}/vite.config.ts"
}
},
"build": {
"executor": "@trackunit/iris-app-sdk-vite:build",
"options": {
"viteConfig": "apps/{app-name}/vite.config.ts",
"outputPath": "dist/apps/{app-name}"
}
}
}
tailwind.config.js (if present)If your app has a tailwind.config.js file, delete it. Tailwind CSS v4 is now configured automatically by the Vite plugin using PostCSS — no manual Tailwind config is needed.
See the Tailwind 4 upgrade changelog for more details on the Tailwind migration.
Remove unwanted packages from your NX's package.json (if present):
@trackunit/iris-app-webpack-plugin@trackunit/iris-app-sdk-rspack@rspack/core@rspack/dev-server,copy-webpack-plugincss-loaderesbuild-loaderstyle-loaderpostcsspostcss-loaderjson-loaderwebpackwebpack-cliwebpack-dev-serverThen install to update your lockfile:
npm install
Run serve and build to verify everything works:
# Start dev server
npx nx run {app-name}:serve
# Production build
npx nx run {app-name}:build
The dev server will start on a port in the range 22220–22229 and print a link to open your app:
✨ Iris App is now started, check it out ✨
https://new.manager.trackunit.com/goto/iris-app-dev
| Option | Type | Default | Description |
|---|---|---|---|
viteConfig | string | — | Path to custom Vite config file (optional) |
port | number | auto (22220-22229) | Dev server port |
host | string | localhost | Dev server host |
skipTypeChecking | boolean | false | Skip TypeScript type checking during dev |
| Option | Type | Default | Description |
|---|---|---|---|
viteConfig | string | — | Path to custom Vite config file (optional) |
outputPath | string | — | Output directory (required) |
skipTypeChecking | boolean | false | Skip TypeScript type checking during build |
To analyze your bundle size, set the BUNDLE_ANALYSE environment variable:
BUNDLE_ANALYSE=true npx nx run {app-name}:build
This generates a stats.html file in the output directory using rollup-plugin-visualizer.
The Vite dev server automatically sets CORS headers for Trackunit domains. If you see CORS errors:
In this version of our Iris App SDK, we have upgraded NX to v22.4.4. Make sure to upgrade your extensions to the latest version of NX.
npx nx migrate 22.4.4
npx nx migrate --run-migrations
Please refer to Maintaining Your Application for more information.
In this version we upgraded the foundation for our tailwind to use tailwind 4.1.18 instead of 3.x.
Effected packages:
Also, many of the React libraries have changed, so make sure to update all Trackunit dependencies.
Use this command to make sure you are updated with all latest Trackunit dependencies
npx npm-check-updates "/@trackunit/" -u
Now you need to install the latest tailwind dependencies
npm install @tailwind/postcss@4.1.18 --save-dev
npm install tailwindcss@4.1.18 --save-dev
After this the 'serve' command will use the correct tailwindcss/postcss and all Trackunit dependencies are updated.
For more information on how it might effect your own tailwind classes in your codebase - check this Migration guide
In this version of the App SDK, we have upgraded Node to the current LTS version 24.11.1. Make sure to upgrade your workspace to at least that version.
If using volta, you can install the latest LTS version of Node by running:
volta install node@lts
or by adding the following to your root package.json
"volta": {
"node": "24.11.1"
}
Otherwise, you can download the latest LTS version of Node from the Node.js website.
Filter states are now automatically synchronized with URL parameters, allowing users to bookmark or share filtered views. When filters are applied, the URL updates to reflect the current filter state, and the filters are restored when navigating back to that URL.
TanStack Router is now required for Iris app extensions using the filter bar.
Your app entry point must be wrapped with TanStack Router's RouterProvider. See the iris-app-with-router-example for a complete implementation example showing how to set up the router in your Iris app extension.
We enhanced the endpoint for setting custom field values to support definition keys as an alternative to definition UUIDs. This improvement eliminates the need to hardcode UUIDs in your integration code, making your implementations more maintainable and readable.
➕ POST: /api/custom-fields/v1/set-values/
Set custom field values