@ -15,13 +15,11 @@
limitations under the License.
limitations under the License.
-->
-->
< div class = "flex items-baseline gap-4 lt-md:-mb-6 " >
< div class = "mb-10 flex items-baseline gap-4 lt-md:mb-4 " >
< ng-content > < / ng-content >
< ng-content > < / ng-content >
@if (!isLoading & & totalElements > 0) {
< span class = "tb-search-results-count tb-search-results-count-mobile" >
< span class = "tb-search-results-count tb-search-results-count-mobile" >
{{ 'iot-hub.results-count' | translate:{ count: totalElements } }}
{{ 'iot-hub.results-count' | translate:{ count: totalElements } }}
< / span >
< / span >
}
< / div >
< / div >
<!-- Search + Sort row -->
<!-- Search + Sort row -->
< div class = "flex items-center gap-4" >
< div class = "flex items-center gap-4" >
@ -56,92 +54,93 @@
< / div >
< / div >
<!-- Results count + Pagination (shown when results exist) -->
<!-- Results count + Pagination (shown when results exist) -->
@if (!isLoading & & totalElements > 0) {
< div class = "tb-search-pagination-row" [ class . lt-md: ! hidden ] = " totalElements = == 0 " >
< div class = "tb-search-pagination-row ">
< span class = "tb-search-results-count ">
< span class = "tb-search-results-count" >
{{ 'iot-hub.results-count' | translate:{ count: totalElements } }}
{{ 'iot-hub.results-count' | translate:{ count: totalElements } }}
< / span >
< / span >
@if (totalElements > 0) {
< div class = "tb-search-pagination" >
< div class = "tb-search-pagination" >
< div class = "flex items-center gap-px" >
< div class = "flex items-center gap-px" >
< button mat-icon-button [ disabled ] = " pageIndex = == 0 " ( click ) = " goToPage ( pageIndex - 1 ) " >
< button mat-icon-button [ disabled ] = " pageIndex = == 0 " ( click ) = " goToPage ( pageIndex - 1 ) " >
< mat-icon > chevron_left< / mat-icon >
< mat-icon > chevron_left< / mat-icon >
< / button >
@for (p of getPageNumbers(); track p) {
< button class = "tb-search-page-btn" [ class . active ] = " p = == pageIndex " ( click ) = " goToPage ( p ) " >
{{ p + 1 }}
< / button >
< / button >
@for (p of getPageNumbers(); track p) {
}
< button class = "tb-search-page-btn" [ class . active ] = " p = == pageIndex " ( click ) = " goToPage ( p ) " >
< button mat-icon-button [ disabled ] = " pageIndex > = totalPages - 1" (click)="goToPage(pageIndex + 1)">
{{ p + 1 }}
< mat-icon > chevron_right< / mat-icon >
< / button >
< / button >
< / div >
< div class = "tb-search-page-size" >
< span > {{ 'iot-hub.items-per-page' | translate }}:< / span >
< mat-select [ value ] = " pageSize " ( selectionChange ) = " onPageSizeChange ( $ event . value ) " class = "tb-search-page-size-select" >
@for (size of pageSizeOptions; track size) {
< mat-option [ value ] = " size " > {{ size }}< / mat-option >
}
}
< button mat-icon-button [ disabled ] = " pageIndex > = totalPages - 1" (click)="goToPage(pageIndex + 1)">
< / mat-select >
< mat-icon > chevron_right< / mat-icon >
< / button >
< / div >
< div class = "tb-search-page-size" >
< span > {{ 'iot-hub.items-per-page' | translate }}:< / span >
< mat-select [ value ] = " pageSize " ( selectionChange ) = " onPageSizeChange ( $ event . value ) " class = "tb-search-page-size-select" >
@for (size of pageSizeOptions; track size) {
< mat-option [ value ] = " size " > {{ size }}< / mat-option >
}
< / mat-select >
< / div >
< / div >
< / div >
< / div >
< / div >
}
}
< / div >
<!-- No results count when 0 -->
< div class = "tb-search-divider" > < / div >
@if (!isLoading & & totalElements === 0 & & searchText?.trim()) {
< div class = "tb-search-pagination-row" >
< span class = "tb-search-results-count" >
{{ 'iot-hub.results-count' | translate:{ count: 0 } }}
< / span >
< / div >
}
<!-- Loading -->
< div class = "relative min-h-0" >
@if (isLoading) {
< div class = "tb-search-loading flex justify-center py-12" >
< mat-spinner diameter = "40" > < / mat-spinner >
< / div >
}
<!-- No results -->
< div class = "tb-results-container" >
@if (!isLoading & & totalElements === 0 & & searchText?.trim()) {
<!-- No results -->
< div class = "tb-search-empty flex flex-col items-center py-10" >
@if (totalElements === 0 & & searchText?.trim()) {
< div class = "tb-no-data-bg" > < / div >
< div class = "tb-search-empty flex flex-col items-center py-10" >
< h3 > {{ 'iot-hub.no-items-found' | translate }}< / h3 >
< div class = "tb-no-data-bg" > < / div >
< p > {{ 'iot-hub.try-adjusting-search' | translate }}< / p >
< h3 > {{ 'iot-hub.no-items-found' | translate }}< / h3 >
< / div >
< p > {{ 'iot-hub.try-adjusting-search' | translate }}< / p >
}
< / div >
}
<!-- Results grouped by type -->
<!-- Results grouped by type -->
@if (!isLoading & & resultGroups.length > 0) {
@if (resultGroups.length > 0) {
< div class = "tb-search-divider" > < / div >
< div class = "tb-search-categories" >
< div class = "tb-search-categories" >
@for (group of resultGroups; track group.type) {
@for (group of resultGroups; track group.type) {
< div class = "tb-search-section" >
< div class = "tb-search-section" >
<!-- Section header -->
<!-- Section header -->
< button mat-button class = "tb-search-section-header" ( click ) = " navigateToType ( group . type ) " >
< button mat-button class = "tb-search-section-header" ( click ) = " navigateToType ( group . type ) " >
{{ getTypeLabel(group.type) }}
{{ getTypeLabel(group.type) }}
< mat-icon > chevron_right< / mat-icon >
< mat-icon > chevron_right< / mat-icon >
< / button >
< / button >
<!-- Card grid -->
<!-- Card grid -->
< div class = "tb-search-card-grid" [ class . tb-search-card-grid-compact ] = " isCompactType ( group . type ) " >
< div class = "tb-search-card-grid" [ class . tb-search-card-grid-compact ] = " isCompactType ( group . type ) " >
@for (item of group.items; track item.id) {
@for (item of group.items; track item.id) {
< tb-iot-hub-item-card
< tb-iot-hub-item-card
[item]="item"
[item]="item"
[installedItem]="getInstalledItem(item)"
[installedItem]="getInstalledItem(item)"
[installedItemsCount]="getInstalledItemsCount(item)"
[installedItemsCount]="getInstalledItemsCount(item)"
[showTypeChip]="false"
[showTypeChip]="false"
[showSubtype]="false"
[showSubtype]="false"
[showCreator]="showCreator"
[showCreator]="showCreator"
(cardClick)="openItemDetail($event)"
(cardClick)="openItemDetail($event)"
(creatorClick)="navigateToCreator($event)"
(creatorClick)="navigateToCreator($event)"
(installClick)="installItem($event)"
(installClick)="installItem($event)"
(updateClick)="updateItem($event)"
(updateClick)="updateItem($event)"
(deleteClick)="deleteInstalledItem($event)">
(deleteClick)="deleteInstalledItem($event)">
< / tb-iot-hub-item-card >
< / tb-iot-hub-item-card >
}
}
< / div >
< / div >
< / div >
}
< / div >
< / div >
}
}
< / div >
< / div >
}
<!-- Loading -->
@if (isLoading) {
< div class = "absolute inset-0 z-10 backdrop-grayscale" style = "background: rgba(255, 255, 255, 0.72)" >
< div class = "flex justify-center py-32" >
< mat-spinner diameter = "64" > < / mat-spinner >
< / div >
< / div >
}
< / div >