Browse Source
Refactor: route all iot-hub dialog.open calls through IotHubActionsService; new openInstalledItems/reviewDevice methods; simpler deleteItem/updateItem signatures reading metadata from installedItem. Extract shared code: - iot-hub-utils.ts — filterIotHubItemsBySearch, groupIotHubFilterItems, resolveIotHubItemImageUrl used by browse, search, widget-select, home - _iot-hub-common.scss — mixins for the 40px search/filter input pattern - device-install-dialog — markEntityStepSuccess and saveRuleChainWithMetadata helpers collapse duplicate blocks - update dialog reuses install dialog's SCSS (styles were byte-identical) Cleanup: - Removed 30+ unused methods, fields, and imports across iot-hub components - Removed 14 unused locale keys (iot-hub.* / item.selected / vendor-placeholder) - Deleted unused SCSS selectors (.dlg-close, .dlg-row-1, dlg-info-actions, etc.) - All router.navigate* calls prefixed with void to satisfy ignored-promise hints IDE diagnostics fixed: - 28 a11y errors — added role/tabindex/keyup.enter to interactive divs/spans - Regex redundant escapes and single-char alternations - Bare boolean attrs (stickyEnd, linear, disabled, showFirstLastButtons) converted to [prop]="true" - Merged background/background-image/background-size shorthand - Removed redundant border-bottom overridespull/15508/head
52 changed files with 503 additions and 1471 deletions
@ -0,0 +1,72 @@ |
|||
/** |
|||
* Copyright © 2016-2026 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
|
|||
// Shared IoT Hub visual building blocks — used across |
|||
// iot-hub-browse, iot-hub-search, and dashboard-widget-select |
|||
// to keep filter / search controls in sync. |
|||
|
|||
@mixin tb-iot-hub-search-container { |
|||
display: flex; |
|||
align-items: center; |
|||
gap: 8px; |
|||
height: 40px; |
|||
padding: 8px 12px; |
|||
border: 1px solid rgba(0, 0, 0, 0.12); |
|||
border-radius: 8px; |
|||
background: white; |
|||
} |
|||
|
|||
@mixin tb-iot-hub-search-icon($color: rgba(0, 0, 0, 0.38)) { |
|||
font-size: 24px; |
|||
width: 24px; |
|||
height: 24px; |
|||
color: $color; |
|||
flex-shrink: 0; |
|||
} |
|||
|
|||
@mixin tb-iot-hub-search-input-text($letter-spacing: normal) { |
|||
flex: 1; |
|||
min-width: 0; |
|||
border: none; |
|||
outline: none; |
|||
padding: 0; |
|||
font-family: inherit; |
|||
font-size: 14px; |
|||
font-weight: 400; |
|||
line-height: 20px; |
|||
letter-spacing: $letter-spacing; |
|||
color: rgba(0, 0, 0, 0.87); |
|||
background: transparent; |
|||
|
|||
&::placeholder { |
|||
color: rgba(0, 0, 0, 0.38); |
|||
} |
|||
} |
|||
|
|||
@mixin tb-iot-hub-search-clear { |
|||
width: 24px; |
|||
height: 24px; |
|||
padding: 0; |
|||
flex-shrink: 0; |
|||
color: rgba(0, 0, 0, 0.38); |
|||
--mdc-icon-button-state-layer-size: 24px; |
|||
|
|||
mat-icon { |
|||
font-size: 18px; |
|||
width: 18px; |
|||
height: 18px; |
|||
} |
|||
} |
|||
@ -1,58 +0,0 @@ |
|||
/** |
|||
* Copyright © 2016-2026 The Thingsboard Authors |
|||
* |
|||
* Licensed under the Apache License, Version 2.0 (the "License"); |
|||
* you may not use this file except in compliance with the License. |
|||
* You may obtain a copy of the License at |
|||
* |
|||
* http://www.apache.org/licenses/LICENSE-2.0 |
|||
* |
|||
* Unless required by applicable law or agreed to in writing, software |
|||
* distributed under the License is distributed on an "AS IS" BASIS, |
|||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|||
* See the License for the specific language governing permissions and |
|||
* limitations under the License. |
|||
*/ |
|||
|
|||
.tb-iot-hub-install-content { |
|||
display: flex; |
|||
flex-direction: column; |
|||
gap: 20px; |
|||
padding: 24px; |
|||
} |
|||
|
|||
.tb-iot-hub-install-title { |
|||
font-size: 20px; |
|||
font-weight: 600; |
|||
line-height: 24px; |
|||
letter-spacing: 0.1px; |
|||
color: rgba(0, 0, 0, 0.87); |
|||
margin: 0; |
|||
} |
|||
|
|||
.tb-iot-hub-install-desc { |
|||
color: rgba(0, 0, 0, 0.54); |
|||
font-size: 14px; |
|||
line-height: 20px; |
|||
letter-spacing: 0.2px; |
|||
margin: 0; |
|||
} |
|||
|
|||
.tb-iot-hub-inline-spinner { |
|||
display: inline-block; |
|||
margin-right: 8px; |
|||
vertical-align: middle; |
|||
} |
|||
|
|||
.tb-iot-hub-error-details { |
|||
max-height: 200px; |
|||
overflow-y: auto; |
|||
padding: 12px; |
|||
background: #f5f5f5; |
|||
border-radius: 4px; |
|||
font-family: monospace; |
|||
font-size: 12px; |
|||
color: rgba(0, 0, 0, 0.7); |
|||
white-space: pre-wrap; |
|||
word-break: break-word; |
|||
} |
|||
@ -0,0 +1,69 @@ |
|||
///
|
|||
/// Copyright © 2016-2026 The Thingsboard Authors
|
|||
///
|
|||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|||
/// you may not use this file except in compliance with the License.
|
|||
/// You may obtain a copy of the License at
|
|||
///
|
|||
/// http://www.apache.org/licenses/LICENSE-2.0
|
|||
///
|
|||
/// Unless required by applicable law or agreed to in writing, software
|
|||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|||
/// See the License for the specific language governing permissions and
|
|||
/// limitations under the License.
|
|||
///
|
|||
|
|||
import { FilterParamInfo } from '@shared/models/iot-hub/iot-hub-item.models'; |
|||
import { MpItemVersionView } from '@shared/models/iot-hub/iot-hub-version.models'; |
|||
import { IotHubApiService } from '@core/http/iot-hub-api.service'; |
|||
|
|||
export const IOT_HUB_FILTER_GROUPING_THRESHOLD = 11; |
|||
export const IOT_HUB_FILTER_POPULAR_LIMIT = 10; |
|||
|
|||
export interface IotHubFilterGroup { |
|||
label: string; |
|||
items: FilterParamInfo[]; |
|||
} |
|||
|
|||
export function filterIotHubItemsBySearch(items: FilterParamInfo[], search: string): FilterParamInfo[] { |
|||
const normalized = (search || '').toLowerCase(); |
|||
if (!normalized) { |
|||
return items; |
|||
} |
|||
return items.filter(item => item.key.toLowerCase().includes(normalized)); |
|||
} |
|||
|
|||
export function groupIotHubFilterItems(items: FilterParamInfo[], search: string): IotHubFilterGroup[] { |
|||
const filtered = filterIotHubItemsBySearch(items, search); |
|||
if (items.length < IOT_HUB_FILTER_GROUPING_THRESHOLD) { |
|||
return [{ label: null, items: filtered }]; |
|||
} |
|||
const topKeys = new Set( |
|||
[...items] |
|||
.sort((a, b) => b.totalInstallCount - a.totalInstallCount) |
|||
.slice(0, IOT_HUB_FILTER_POPULAR_LIMIT) |
|||
.map(i => i.key) |
|||
); |
|||
const popular = filtered.filter(i => topKeys.has(i.key)); |
|||
const rest = filtered.filter(i => !topKeys.has(i.key)); |
|||
const groups: IotHubFilterGroup[] = []; |
|||
if (popular.length) { |
|||
groups.push({ label: 'iot-hub.most-popular', items: popular }); |
|||
} |
|||
if (rest.length) { |
|||
groups.push({ label: 'iot-hub.all', items: rest }); |
|||
} |
|||
return groups; |
|||
} |
|||
|
|||
export function resolveIotHubItemImageUrl(item: MpItemVersionView, api: IotHubApiService): string | null { |
|||
if (item.image) { |
|||
return api.resolveResourceUrl(item.image); |
|||
} |
|||
const resource = item.resources?.find(r => r.type === 'SCREENSHOT') || item.resources?.find(r => r.type === 'ICON'); |
|||
if (resource) { |
|||
return api.resolveResourceUrl(`/api/resources/${resource.id}`); |
|||
} |
|||
return null; |
|||
} |
|||
Loading…
Reference in new issue