Align the four entity table "Add from IoT Hub" descriptors (devices,
rule chains, calculated fields, widget types) with the new hub icon
already used by the IoT Hub menu and breadcrumb. Drops the old
`store` glyph that no longer matches the rest of the IoT Hub UI.
- IotHubRestClient.getVersionFileData now streams the response and
enforces a configurable size cap (iot-hub.max-file-data-size-bytes,
env IOT_HUB_MAX_FILE_DATA_SIZE_BYTES, default 100 MiB). Oversized
payloads are rejected up front via Content-Length and mid-stream
for chunked transfers, preventing OOMs from unknown bodies.
- DefaultIotHubService guards every iotHubRestClient.getVersionInfo
call against a null response, and rejects update attempts where
the installed item's type does not match the new version's type
("Installed item type does not match the new version's item type.").
Solution-template descriptor is also populated with
tenantTelemetryKeys / tenantAttributeKeys captured during install.
Drops the empty updateDeviceProfile stub.
- Add a tenant-scoped findByTenantIdAndId + deleteByTenantIdAndId to
IotHubInstalledItemDao (and the bulk deleteByTenantIdAndIdIn JPA
query). IotHubInstalledItemServiceImpl now uses these so reads
and deletes always honour the tenant boundary.
- Database: add lts schema_update.sql + schema-entities-idx.sql
indexes on iot_hub_installed_item(tenant_id),
(tenant_id, item_type), and (tenant_id, item_id) for the new
tenant-scoped lookups.
- DefaultSolutionService: minor cleanup touched alongside.
- .gitignore trailing-newline fix; remove stale superpowers
plan/spec docs that have been folded into the implementation.
- New input[matAutocomplete]/textarea[matAutocomplete] directive
that keeps an open MatAutocomplete panel attached to its anchor
while the page scrolls or the window resizes: tracks the
input's visibility via IntersectionObserver and re-requests
panel position (or closes the panel when off-screen) when the
nearest scroll container or window emits a resize/scroll event.
- Declare and export the directive from SharedModule so it lights
up across every screen that uses mat-autocomplete.
- Drop the transparent backdrop from
MAT_AUTOCOMPLETE_DEFAULT_OPTIONS (the directive now handles
scroll-and-resize repositioning, so the backdrop-driven outside-
click close is no longer needed) and keep the existing
hideSingleSelectionIndicator default.
Add a DEVICE arm to getInstalledItemUrl so device-installs link to
their generated dashboard (descriptor.dashboardId / EntityType.DASHBOARD),
matching the existing SOLUTION_TEMPLATE handling instead of falling
through to no URL.
Bump the installed-items table .mat-column-createdTime width
from 100px to 160px so the new "MMM d, y, h:mm a" format
(introduced when the column started showing the install time)
fits without wrapping or ellipsis.
Switch the createdTime column formatter from 'mediumDate' (date
only) to the custom pattern 'MMM d, y, h:mm a' so each row also
surfaces the install time. Angular's built-in 'medium' alias was
not used because it includes seconds.
- Guard the helper against a missing descriptor by short-circuiting
to null up front instead of letting the switch crash on
`undefined.type`.
- Expand the inline single-line `case 'X': … break;` arms in the
switch so each branch reads on its own line, matching the
formatting of the already-multi-line CALCULATED_FIELD /
ALARM_RULE arms.