Spend the 10*timeoutMultiplier budget across messages instead of
resetting it per message, so a stream of non-matching events can't
extend the wait indefinitely.
Saving the shared attribute also triggers an attribute-update push on
v1/gateway/attributes (gateways auto-receive updates for connected
devices). That push can reach the listener queue before the request
response, so the blind poll occasionally parsed the update message
(no 'shared' field) instead of the response, failing on CI.
Poll until an event arrives on v1/gateway/attributes/response.
New clientKeys/sharedKeys format (empty=all) sets separateScopesResponse -> new
{client,shared} response; legacy client+key/keys keeps value/values. Neither marker
=> fetch all with new response (also fixes the omit-keys session crash).
Actor getAttributesKvEntries: explicit per-scope all/specific/none with all-wins;
both-absent keeps the 'fetch everything' backward-compat. Echo separateScopesResponse
request->response. JsonConverter.getJsonObjectForGateway emits {client,shared} when
separateScopesResponse, else legacy value/values. Unit test for the converter.
Push the deleteInstalledItem call from IotHubActionsService into the dialog's confirm() handler so the dialog itself manages its lifetime. Pass installedItemId in the dialog data and have confirm() fire the API call, then close with true on success. Drop the now-unused isLoading flips in the installed-items table since loading state is no longer optimistically toggled around the dialog.
PROD-8423: .tb-main-content (the scroll container holding the router-outlet in home.component.html) keeps its scrollTop across route changes, so navigating from a scrolled-down IoT Hub home to a child page (e.g. Calculated Fields) opened the new page already scrolled. Angular's scrollPositionRestoration only handles window scroll, not arbitrary containers. Add a #mainContent ref, capture the ElementRef, and reset its scroll position in the existing (activate) handler so every route navigation lands at the top.
PROD-8420: .tb-iot-hub-sort-row was locked to height: 32px, so when many use-case filters were selected the chip-set wrapped to multiple lines but the row stayed one line tall and the card grid below rendered on top of the wrapped chips. Switch to min-height: 32px so the row keeps its baseline single-line height when empty but grows naturally with wrapped chips.
IotHubActionsService.deleteItem now returns true/false (no cancel-as-EMPTY) and updateItem returns string|boolean; callers no longer early-return on a null installed item and instead let the service produce a false, so the subscriber consistently fires. Installed-items table shows a translucent loading overlay during update/delete via isLoading + relative-positioned container. Replace mr-2 inline-block align-middle hacks on dialog button spinners with matButtonIcon, and use matButtonIcon for the check-for-updates button icon/spinner too.
Detail dialog non-CF/RC layout stacks the preview and description on lt-md instead of overflowing horizontally. Hero cluster moves up to 15% and title drops to 28px on the smallest viewport. getInstalledItemUrl for DEVICE descriptors now falls back to the first DEVICE entry in createdEntityIds when dashboardId is missing, so single-device packages still resolve to an entity URL.
* Fixed Advanced Widget Style Editor rendering
(cherry picked from commit 32ddf4336b)
* Moved styles to class for styles consistency
(cherry picked from commit 0b306159ba)
Wrap the creator description and social-link block in a flex column that takes the remaining height with overflow-y:auto, so long bios scroll inside the left rail instead of pushing the avatar off-screen. Lock the avatar's min-height to keep its circle from collapsing.