- New addItem(itemType, options?) method opens add item dialog via service
- Options: optional itemSubType and entityId
- Refactored dashboards, rule chains, devices, widget types, calculated fields
to use iotHubActions.addItem() instead of opening dialog directly
- Removed direct TbIotHubAddItemDialogComponent imports from all table configs
- All table configs now inject IotHubActionsService
- New iot-hub-components.models.ts with shared ITEM_TYPE_TO_ENTITY_TYPE
mapping and resolveEntityDetailsUrl function
- Remove duplicated ITEM_TYPE_TO_ENTITY_TYPE from install and update dialogs
- Remove duplicated resolveEntityDetailsUrl from install and update dialogs
- Both dialogs now use shared function from models file
- Make installDevice public in IotHubActionsService
- Add item dialog: for DEVICE type, invoke iotHubActions.installDevice
instead of standard install flow
- Add "Add from IoT Hub" action to devices table (tenant scope)
- Update IotHubModule to import IotHubComponentsModule instead of HomeComponentsModule
- Update CLAUDE.md with IotHubActionsService and IotHubComponentsModule docs
- New IotHubActionsService with openItemDetail, installItem, updateItem,
deleteItem methods returning Observables for dialog results
- Service handles all dialog opening, device install flow (fetch zip + dialog),
and delete confirmation + API call
- Registered as provider in IotHubComponentsModule
- Refactored browse component: removed all dialog imports, uses service
- Refactored home component: removed dialog imports, uses service
- Refactored search component: removed dialog imports, uses service
- Removed ~150 lines of duplicated dialog code across 3 components
- Move iot-hub-install-dialog to home/components/iot-hub/
- Move iot-hub-update-dialog to home/components/iot-hub/
- Move iot-hub-delete-dialog to home/components/iot-hub/ (with new separate HTML/SCSS)
- Move device-install-dialog to home/components/iot-hub/device-install-dialog/
- Register all in HomeComponentsModule (declarations + exports)
- Remove from IotHubModule declarations
- Update all imports across home/browse/search/installed/detail/widget-select
- Remove iotHubApiService from IotHubItemDetailDialogData, inject in constructor
- Remove iotHubApiService from IotHubInstallDialogData, inject in constructor
- Remove iotHubApiService from IotHubUpdateDialogData, inject in constructor
- Remove iotHubApiService from DeviceInstallDialogData, inject in constructor
- Update all callers (home, browse, search, installed items, widget select,
item detail dialog) to remove iotHubApiService from dialog data
- Fix device install dialog data (item + zipData) after bulk removal
- IotHubApiService injected in dialog constructor, removed from data interface
- Add optional entityId to dialog data, passed to installItemVersion for CF
- Add optional itemSubType to dialog data and fixedSubType to browse component
- fixedSubType: applies subtype filter, hides subtype filter section/chips,
excluded from active filters and clear all, hides card subtype badge
- Add "Add from IoT Hub" to calculated fields table with entityId
- Rule chains: pass CORE/EDGE subType based on ruleChainScope, fix navigation
- Show alert dialog on install failure with error details
- Remove IotHubApiService from all dialog data callers
- Add 'add' mode to item card: shows "Add" button, emits addClick
- Add 'add' mode and addItem output to browse component
- Browse passes mode to cards and detail dialog, propagates add results
- New TbIotHubAddItemDialogComponent: fullscreen dialog with embedded browse
in add mode, installs item via API and returns descriptor
- Add "Add from IoT Hub" menu item to dashboards table config
- On add: installs dashboard, navigates to newly created dashboard
- Add HomeComponentsModule import to IotHubModule
- Move iot-hub-browse.component to home/components/iot-hub/
- Move iot-hub-item-card.component to home/components/iot-hub/
- Register both in HomeComponentsModule (declarations + exports)
- Remove from IotHubModule declarations
- Update relative imports to use @home/pages/iot-hub/ for dialog dependencies
- Add All/Installed toggle in IoT Hub mode header
- Installed mode fetches published versions for installed widgets with in-memory filtering
- Filter panel with Type, Category, Use Case sections via tb-popover
- Filter badge count on filter button
- Installed badge (check + label) on widget cards in All mode
- Widget type badge from dataDescriptor on IoT Hub widget cards
- Filters apply to both All (server-side) and Installed (in-memory) modes
- Load installed widgets on entering IoT Hub mode
- Skip detail dialog for already-installed widgets, emit directly
- Move item detail dialog to home/components/iot-hub for shared access
- Register in HomeComponentsModule (declarations + exports)
- Add 'add' mode to item detail dialog showing "Add" button instead of install
- Add 'iotHub' mode to dashboard-widget-select with IoT Hub widget grid
- IoT Hub cards show author + install count footer
- Clicking card opens detail dialog in 'add' mode
- Add installs widget via IoT Hub API then emits widgetSelected with full type info
- Add "IoT Hub" option to mode toggle in dashboard page header
- Hide filter/deprecated controls in IoT Hub mode
- Hero keywords clickable to navigate to items pages
- Use subscriptSizing="dynamic" on hero search and search page inputs
- Replace native select with mat-select for items-per-page in search page
- Propagate search text to type pages via ?search= query param
- Remove back button negative margin
- New TbIotHubSearchComponent at /iot-hub/search with ?search= query param
- Results grouped by item type with section headers linking to type pages
- 5-column grid for widgets/dashboards, 3-column for calculated fields/rule chains
- Search input with clear button, sort dropdown, pagination with page numbers
- Empty state with search_off icon when no results found
- Reuses item card component with install/update/delete dialog handling
- Search popup using mat-autocomplete with results grouped by item type
- Debounced search with distinctUntilChanged, page size 10, most installed sort
- Loading spinner shown immediately on first focus while fetching
- No results state with search_off icon and contextual message
- Clear button in search input to reset text
- "See all results" footer navigates to /iot-hub/search page
- Search button performs same navigation as "See all results"
- Popup styled to match design: 424px max-height, 8px radius, layered shadow
- Update table type chips, update column, and filter panel to match design
- Add afterClosed handling to viewItemDetails and viewUpdateDetails dialogs
- Reload table data when items are updated or deleted from detail dialog
- Back link + "Installed Items" title + "Check for updates" primary button
- Filter button (stroked primary) with dropdown checkbox panel for item types
- Filter chips (mat-chip-set) with "Clear all" button when active
- Search field matching browse page design (320px, rounded-8, outlined)
- Mat-table with columns: Name, Type (colored icon+text), Version,
Installed date, Updates (up-to-date/available+update btn), Actions
- Actions: info, open-in-new, remove (mdi:trash-can-outline) icon buttons
- Updates column: green "Up to date" or "vX.X.X Available" + Update stroked warn
- Item type filter passed as List<String> to API
- Use TbIotHubDeleteDialogComponent for remove confirmation
- Item card: installed chip (non-clickable pill, green) + separate remove icon
button (mdi:trash-can-outline) for both same-version and update-available states
- Detail dialog: info section matches design exactly (badge, links, actions layout),
solution template links on separate row, remove button with warn outline matching
label text color, matButtonIcon + tb-mat-24 on remove icon
- Rename all Delete labels/keys to Remove across locale and components
- Solution template remove dialog: specific description about multiple entities
- getInstalledItems API: change itemType to List<String> itemTypes through full stack
(controller, service, DAO, repository JPQL uses IN clause, UI accepts string|string[])
* Add device-package.models.ts with install wizard types
Defines ConnectivityType, InstallStepType, ENTITY_STEP_TYPES,
stepTypeAliasMap, DevicePackageInfo, DeviceInstallStep, form field
interfaces, and EntityStepProgress types for the device install wizard.
* Add device install wizard dialog component for IoT Hub
Multi-step dialog that provisions TB entities from a device package ZIP:
- Connectivity type selector, instruction/markdown views, dynamic forms
- Entity creation with progress tracking (device profile, device, dashboard, rule chain)
- Variable resolution across steps (form values, entity outputs, positional refs)
* fix(iot-hub): fix device install dialog template and translations
- Use correct tb-markdown inputs ([data] and [usePlainMarkdown])
- Fix translation key format (hyphens, not dots)
- Remove unused ConnectivityType import and resolveImageUrl method
- Auto-advance to first step when single connectivity type
- Use inline data URIs for helpImage directly
* feat(iot-hub): wire device install dialog into all install entry points
Branch DEVICE item type to fetch ZIP and open TbDeviceInstallDialogComponent
instead of the simple install dialog. Applied to:
- Item detail dialog (install button)
- Browse component (card install button)
- Home component (card install button)
* fix(iot-hub): fix build errors in device install dialog
- Fix tb-markdown input: [markdownText] → [data] in done view
- Fix JSZip entry type annotation for strict TS compilation
* fix(iot-hub): reuse existing device profiles and add missing retry translation
- Find device profile by name before creating; reuse if exists
- Add action.retry translation key (was showing raw key)
* feat(iot-hub): add find-or-create for rule chains in device install
Reuse existing rule chains by name (same pattern as device profiles).
Shared entities (device profile, rule chain) are looked up before creation.
Per-install entities (device, dashboard) are always created fresh.
* feat(iot-hub): refactor device install dialog to use mat-stepper
- Replace single-panel view switching with mat-horizontal-stepper
- Group consecutive entity steps into a single "Provisioning" stepper step
- Each SHOW_INSTRUCTION and SHOW_FORM is its own stepper step
- Add 2s minimum display time per entity creation step
- Connectivity selector shown before stepper (not a stepper step)
- Progress step auto-advances to next step after completion
- Stepper shows completed checkmarks for finished steps
* fix(iot-hub): fix stepper navigation by tracking step completion
Linear mat-stepper requires steps to be marked completed before
advancing. Added completed flag to WizardStep, set it when user
clicks Next or when entity steps finish.
* feat(iot-hub): add device package install tracking with entity cleanup
Backend:
- Expand DeviceInstalledItemDescriptor with createdEntityIds and dashboardId
- Add POST /api/iot-hub/device/register endpoint to save installed item
- Implement reverse-order entity deletion for DEVICE uninstall
- Update DEVICE case in updateItemVersion to clean old entities
Frontend:
- Expand DeviceInstalledItemDescriptor TS model
- Add registerDeviceInstall API method
- Wire wizard to collect entity IDs and register after completion
- Enable dashboard navigation for installed device packages
* fix(iot-hub): add type discriminator to device register request body
Jackson requires the 'type' field for @JsonTypeInfo polymorphic
deserialization of DeviceInstalledItemDescriptor.
* feat(iot-hub): show entity type in provisioning progress rows
Each progress row now displays "Device Profile — ESP32 Dev Kit" instead
of just "ESP32 Dev Kit", making it clear what type of entity is being
provisioned.
* fix(iot-hub): suppress global error toast and add Back button on provisioning error
- Add ignoreErrors: true to all entity creation API calls so errors
are only shown in the dialog, not as global toast notifications
- Add Back button on provisioning error to navigate back to the last
form step, allowing users to fix parameters (e.g. device name)
- Make form steps editable so stepper allows backward navigation
- Reset progress step state when going back so it re-runs with
updated form values
* fix(iot-hub): resolve ExpressionChangedAfterItHasBeenCheckedError in device install dialog
Inject ChangeDetectorRef and call detectChanges() after async state
mutations (entity step status changes, stepper auto-advance, ngOnInit
completion). The NG0100 error occurred because async operations
(setTimeout, HTTP calls) mutated component state outside Angular's
change detection cycle.
* fix(iot-hub): fix device register endpoint JSON deserialization
Accept JsonNode and use JacksonUtil.treeToValue() instead of direct
@RequestBody DeviceInstalledItemDescriptor. The @JsonTypeInfo on the
parent interface caused Spring's message converter to fail when
deserializing the concrete class directly.
* fix(iot-hub): fix dashboardId serialization in device register request
DashboardId implements EntityId which uses EntityIdDeserializer requiring
both entityType and id fields. Frontend was sending {"id":"..."} without
entityType, causing "Missing entityType or id!" 400 error.
Fix: include entityType: "DASHBOARD" in the dashboardId payload.
Add deserialization unit test to verify the exact frontend payload format.
- Create TbIotHubItemsPageComponent with hero section (title, description,
illustration, installed items button, contribute link) per item type
- Add separate routes: /iot-hub/widgets, /iot-hub/dashboards,
/iot-hub/solution-templates, /iot-hub/calculated-fields,
/iot-hub/rule-chains, /iot-hub/devices
- Remove old /iot-hub/browse route, update all navigation links
- Browse component: add @Input activeType and hideTabs for embedded use
- Home component: navigateToBrowse now routes to type-specific pages
- Add item type page description translations
- Two-column layout: left sidebar filters (280px, own scroll) + right card grid
- Filters use mat-expansion-panel accordions with checkbox lists
- Type, Category, Use Case filter sections with expand/collapse
- Top bar: results count + search field, sort button with mat-menu
- Active filter chips row with clear all button
- 4-column card grid (responsive: 3 at 1200px, 2 at 900px)
- Card subtype label: @Input showSubtype, 12px Medium uppercase above name
- Tabs use plural item type translations
- Remove old header, filter dropdowns, and footer sections
- Add getInstalledItemsCount endpoint through full stack (controller → DAO)
with optional itemType filter
- Add getInstalledItemsCount to UI IotHubApiService
- Home page: show "Installed Items: N" stroked button at top-right when
count > 0, white bg, primary border, card shadow; navigates to installed items
- Count updates on install/delete via API re-fetch and local decrement
- Move IoT Hub menu item right after Dashboards in sidebar
- Create TbIotHubDeleteDialogComponent with warn-colored "Delete anyway" button
- Extract install dialog template and styles to separate HTML/SCSS files
- Install dialog: simplified confirm/success layout matching design, "Close"
label when only button shown on success
- Item card: installed label is now a clickable button emitting deleteClick
- Detail dialog: 64px colored icon header for CF/RC types, description-only
layout (no image) for CF/RC, delete button (stroked warn) in footer when
installed, closes with 'deleted' result after confirmed deletion
- Home component: handle install/delete dialog results by reloading installed
items, pass installedItem to detail dialog
- Rewrite item detail dialog to match design: new header with subtitle row,
side-by-side image+description layout, category/use-case chips section,
markdown readme with style overrides, Close+Install footer buttons
- Description uses tb-markdown component with matching style overrides
- Installed label: check icon + text, no background, TB CE primary color
- Home page fetches installed widgets and solution templates, passes
installedItem to cards and detail dialog
- Replace "Figma" with "Design" in all source code comments
- Create TbIotHubHomeComponent as default route at /iot-hub
- Move browse page to /iot-hub/browse, accept type/search query params
- Interactive hero: hoverable keywords cycle through item types with color changes,
background gradient transitions, and floating icon animations
- Page load animation: hero and categories fade in with slide (down/up)
- Category cards: 3x2 grid with exact Figma gradients and separated title/image layout
- Popular sections: 5-column grid for widgets/dashboards/solutions,
3-column grid for calculated fields/rule chains
- Become a Creator footer section
- Export category card images and hero floating icons from Figma
- Add plural item type translations and home page locale keys
- Add @Input installedItem to card component with install/installed/update states
- Add updateClick output to card, wire update dialog from browse component
- Add itemType filter to getInstalledItems across full stack (controller → DAO)
- Fetch installed solution templates on browse page when tab selected
- Pass installedItem to detail dialog from browse component
- Reload items on install/update dialog close for solution templates
- Add MpItemVersionResource model and resources field to MpItemVersionView
- Add image carousel (ngx-hm-carousel) to detail dialog for solution templates
- Carousel: screenshots preferred over icons, autoplay 3s, dots below images
- Add SolutionService with install/delete/rollback flow, entity provisioning
(customers, assets, devices, dashboards, edges, rule chains, CFs, users),
telemetry emulators, instructions templating, and public customer support
- Add SolutionInstallDialogComponent in home/components/solution with markdown
details display and "Go to main dashboard" navigation
- Update IoT Hub install dialog to open solution dialog on template success
- Add SOLUTION_TEMPLATE type support across frontend (item cards, detail dialog,
installed items table with dashboard entity mapping)
- Add solution instructions button to item detail dialog for installed templates
- Update edge detail URLs and dashboard links for correct CE routing