SystemPatchApplier now creates widget types missing from the DB
instead of throwing, and merges new fqns into existing system bundles.
Bundle creation and inline widgetTypes in bundle JSONs are explicitly
rejected as out-of-scope for patch upgrades.
- Add a clearFilters output + hasActiveFilters() helper to
TbIotHubInstalledItemsTableComponent and render a primary
"Clear all filters" button in the empty state when search or
type filters are active. The parent installed-items page binds
the output to its clearAllFilters() and now also resets
textSearch / appliedTextSearch alongside the type filters.
- Restore the 24px bottom margin on the empty-state body paragraph
so the button has the same breathing room as in the browse
component empty state.
- Update the installed-items page filter panel: remove DASHBOARD,
add ALARM_RULE, and reorder to the canonical
DEVICE → SOLUTION_TEMPLATE → WIDGET → CALCULATED_FIELD →
ALARM_RULE → RULE_CHAIN order shared with home and search.
- Replace the plain text empty placeholder with the same illustration +
title + subtitle layout used by tb-iot-hub-empty-state in the browse
component (no-data illustration, 18/500 title, 14/0.54 body).
- Add a no-installed-items-text locale key ("Try adjusting your search
or filters.").
- Make the table wrapper a flex column and place the empty state and
loading spinner inside it as flex-1 children so both vertically
centre below the sticky header instead of pinning to the top.
- Add a dedicated alarm-rules hero SVG (560×276) and point the
ALARM_RULE PAGE_CONFIG to it instead of the stale dashboards image.
- Replace the calculated-fields and devices hero SVGs with the
updated illustrations exported from the design.
The Installed / IoT Hub toggle now carries icon templates that don't
collapse cleanly into a mat-select on xs viewports — keep the toggle
buttons at every breakpoint instead.
- Add a `template?: TemplateRef<any>` slot to ToggleHeaderOption +
ToggleOption so callers can render arbitrary content inside a
toggle (the existing string label / error icon path stays the
default).
- Use it in the dashboard widget-select header to render a tb-icon
next to each label: now_widgets for Installed, hub for IoT Hub.
- Style the top-level toggle with a 42px pill (8px radius, white-15
border, 40px buttons, 36px line-height, 500 weight) so the icon +
label sit comfortably and contrast against the primary toolbar.
- Apply the same DEVICE → SOLUTION_TEMPLATE → WIDGET → CALCULATED_FIELD →
ALARM_RULE → RULE_CHAIN ordering to the home search popup and the
search component, so all entry points group results consistently.
- Drop DASHBOARD entirely from the search component (route, installed
counts, type order) and filter it out of the home search popup
groups.
- Add ALARM_RULE to the search component (compact-card layout, route
alarm-rules, installed-count handling).
- Remove the "Add from IoT Hub" header action and addDashboardFromIotHub
handler from the dashboards page, plus the now-unused
IotHubActionsService / ItemType imports and constructor injection.
- Reorder category cards to match the design: Devices → Solutions →
Widgets → Calculated Fields → Alarm Rules → Rule Chains.
- Replace gradient card backgrounds with the design's flat per-card
colors and swap stale SVG illustrations for fresh PNG renders
exported from the design.
- Implement the design's hover interaction (200ms ease-out): the card
image scales up by 5.4 % (matching the 387×148 → 408×156 frame
growth) and a chevron slides in next to the title.
- Add the "Most popular in IoT Hub" h2 plus a full-width bleed divider
between the category cards and the popular sections.
- Drop the "Popular " prefix from popular section headers and use
item.type-*-plural translations directly. Remove the now-unused
iot-hub.popular-* locale keys.
- Reorder popular sections to match the design's order.
- Switch the IoT Hub menu and breadcrumb icons from `store` to `hub`.
Spring Boot 3.5.14 ships an ImportsContextCustomizer change that
double-registers legacy @SpyBean fields, causing "Duplicate spy definition"
failures during ApplicationContext load in tests that mix @SpyBean and
@MockitoSpyBean across the test class hierarchy. Pin the test artifacts
to 3.5.13 until 3.5.15+ is released with a fix; runtime stays on 3.5.14
so the CVE fixes remain in effect.
- Restructure HTML Container settings into a mat-tab-group (Resources /
HTML / CSS / JavaScript) instead of a single resources expansion panel
followed by stacked editor blocks. Each editor tab uses [fillHeight]
so the editors fill the panel.
- Wire fill-height plumbing: tb-widget-settings host h-full, basic and
advanced settings @HostBinding('style.height')='100%', advanced panel
switched from inline height:100% to flex-1, mat-content height:100%.
- Register html_container in widget_bundles/html_widgets.json so the
widget appears in the HTML Widgets bundle.
- Replace the placeholder html-card image reference with a dedicated
html-container.png asset and embedded data.
- Add 'JavaScript' translation key for the new tab label.
Under `mvn -T<n>` with the three yarn-using modules (ui-ngx,
msa/web-ui, msa/js-executor), concurrent yarn 1.x processes contend
on the shared `~/.cache/yarn`. The `--mutex network` flag was applied
only to `yarn install`, so `yarn run pkg` could overlap with another
module's install. Intermittent failures observed on CI:
`/bin/sh: 1: tsc: not found` during `yarn run pkg`, caused by
incomplete typescript extraction into per-module node_modules.
Fix at two layers:
1. Maven reactor chain (primary): add reactor-only pom <dependency>
entries (type=pom, scope=provided, wildcard exclusions) to form
ui-ngx -> msa/web-ui -> msa/js-executor
so the MultiThreadedBuilder schedules them strictly serial,
regardless of -T thread count. msa/web-ui already had a real
dependency on ui-ngx; only one new fake link was needed.
2. Yarn-level mutex (defense in depth): add `--mutex network` to
`yarn run pkg` (msa/web-ui, msa/js-executor) and
`yarn run build:prod` (ui-ngx), so single-module builds outside the
reactor chain (`mvn -pl msa/<module>`) still serialize against any
other yarn process on the agent.
Comment in msa/pom.xml updated: the previous "Modules order is
important..." note was misleading - module order in the reactor does
not enforce serialization under -T; the dependency edges do.
- Replace per-type icon SVG sets with single composite cluster SVGs
exported from the updated design (devices, solutions, widgets,
calculated fields, alarm rules, rule chains).
- Add soft per-type colored glow blobs (Ellipse 399 / 400, opacity 0.16,
filter: blur(120px)) at the page level so the wash spans the whole
page background instead of being clipped by the hero.
- Fix hero icons transition: switch from vertical translate to a uniform
scale around the hero centre so icons burst from / collapse to the
centre on enter/exit, matching the design prototype.
- Drive blob fill via [style.color] + currentColor for smooth per-type
tint cross-fades.
Remove the no-longer-used ViewContainerRef injection and the commented-
out fallback branches now that initAngularComponent uses the
angularContainer view container exclusively.
- Group tomcat, commons-lang3 version properties under spring-boot.version
- Drop thymeleaf override (PE-only dependency, not present in CE)
- Drop lz4 plumbing: kafka-clients 3.9.2 and cassandra-all 5.0.7 now transitively ship at.yawk.lz4:lz4-java, making the Dec 2025 CVE hack obsolete
- Fill description and tags for the HTML Container widget type JSON.
- Add basic config component (plain HTML / Angular mode editor).
- Add advanced settings component and shared common settings.
New static widget that replaces the dashboard layout with configurable
HTML, CSS, and JavaScript and exposes the WidgetContext to the user
script. Use for custom complex visualizations or actions when system
widgets are not enough.
AbstractTbQueueConsumerTemplate.poll() returned emptyList() immediately
when partitions was empty, bypassing both doPoll() and the secondary
sleep guard (which is also skipped for backends that report
isLongPollingSupported()==true, e.g. Kafka). The result was a
permanent CPU-burning loop on consumers whose partition assignment
ended up empty after a rebalance cascade — observed on 26
ie-downlink-consumer threads (~244% total CPU) until container restart.
Route the empty-partition path through sleepAndReturnEmpty() so the
caller honors durationInMillis regardless of long-polling support.
Moved NioEventLoopGroup allocations into the try block so that a
constructor failure for the second group no longer leaks the first.
Channel close failures during cleanup now attach via addSuppressed
instead of replacing the original BindException. Narrowed the outer
catch from Throwable to Exception, removing the brittle (Error) cast
that would have masked any direct Throwable subclass.
The base image thingsboard/openjdk17:bookworm-slim ships a customized
/etc/java-17-openjdk/security/java.security. When apt-get install pulls
in a newer openjdk-17-jre-headless to satisfy cassandra's java11-runtime
dependency, dpkg blocks on a non-interactive conffile prompt and the
build fails. The ensuing "cassandra depends on java11-runtime" error is
just the cascade from openjdk-17-jre-headless never finishing configure.
Pass --force-confdef --force-confold so dpkg silently keeps the base
image's customized conffile and the upgrade completes.
Redesigned the top search input on iot-hub-browse, iot-hub-search, and
the installed-items page to share a single page-level field style:
56px tall, 8px radius, 1px light border, white background, 16px input
text, with a 40px round trailing action that shows a non-clickable
search icon when empty and switches to a clickable close icon-button
when text is entered.
Layout updates:
- Browse: search input + sort button now share a single row at the top
(sort moved out of the filter-chips row); the filter-toggle button
moved to the filter-chips row right-aligned (mobile only). Sort row
is 32px tall with 16/12px vertical margin and zero chip margins.
- Search: input fills the row up to the sort button; placeholder is
'Search published items...' on creator profiles, 'Search...' otherwise.
- Browse search input placeholder is per-type ('Search widgets...',
'Search solution templates...', etc.) via searchPlaceholderKey getter.
- Installed items: filter button + chips on a top row, search input on
a dedicated row below; chips margin-top/bottom zeroed.
Common SCSS:
- Added tb-iot-hub-page-search-container / -input / -action mixins to
_iot-hub-common.scss; browse, search, and installed-items pull them
via @include.
- Locale: new iot-hub.search-published-items key.
* feat(iot-hub): scaffold ALARM_RULE item type and CREATOR_VISIBLE_ITEM_TYPES
* feat(iot-hub): wire ALARM_RULE through browse, item card, detail dialog, installed items, and install dialog
* feat(iot-hub): reorder home cards, hide Dashboards, add Alarm Rules
* feat(iot-hub): scaffold ALARM_RULE descriptor and reject install with v4.3 upgrade hint
Registers AlarmRuleInstalledItemDescriptor in the Jackson polymorphism so
4.2 can browse Alarm Rule items from the marketplace without descriptor
deserialization failures.
The install handler explicitly rejects ALARM_RULE with a friendly message
asking the user to upgrade to v4.3+. The full install/update/delete
implementation depends on CalculatedFieldType.ALARM (added in v4.3) and
will land once master is merged into this branch.
* feat(iot-hub): hide redundant Type filter on Alarm Rules browse
* feat(iot-hub): show v4.3 update info dialog directly when installing an Alarm Rule
Relocate the iot_hub_installed_item CREATE TABLE statement from the
basic schema_update.sql to the LTS cumulative schema_update.sql, where
it belongs for this LTS line.
STRING and PASSWORD fields in SHOW_FORM gain optional randomGenerator,
randomSize, and randomByDefault properties. randomByDefault pre-fills the
field on form open; an autorenew icon (next to the eye toggle on PASSWORD)
regenerates on demand. Reuses generateSecret from @core/utils.
Two new markdown placeholders, ${product.button} and ${datasheet.button},
render as inline buttons linking to the manufacturer's product page and
datasheet. They work in SHOW_INSTRUCTION steps (install dialog) and in
overview.md (detail dialog readme). URLs come from device-info.json's
productURL/datasheetURL — install reads from the parsed package, detail
dialog reads from item.dataDescriptor.