]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: empty-data-message 66803/head
authorSagar Gopale <sagar.gopale@ibm.com>
Tue, 6 Jan 2026 07:56:42 +0000 (13:26 +0530)
committerSagar Gopale <sagar.gopale@ibm.com>
Mon, 12 Jan 2026 09:49:48 +0000 (15:19 +0530)
Fixes: https://tracker.ceph.com/issues/74324
Signed-off-by: Sagar Gopale <sagar.gopale@ibm.com>
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-gateway-group/nvmeof-gateway-group.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-namespaces-list/nvmeof-namespaces-list.component.html
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/nvmeof-subsystems/nvmeof-subsystems.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/components/icon/icon.component.scss
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/datatable.module.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html
src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts
src/pybind/mgr/dashboard/frontend/src/app/shared/enum/icons.enum.ts

index e2f6c75879ff67c3b1d4487f4261508592361d2f..a06b87feb670855e7db54d14edeffc481f6477e0 100644 (file)
@@ -7,7 +7,11 @@
     selectionType="single"
     identifier="name"
     (updateSelection)="updateSelection($event)"
-    (fetchData)="fetchData()">
+    (fetchData)="fetchData()"
+    emptyStateTitle="No gateway group created"
+    i18n-emptyStateTitle
+    emptyStateMessage="Set up your first gateway group to start using NVMe over Fabrics. This will allow you to create high-performance block storage with NVMe/TCP protocol."
+    i18n-emptyStateMessage>
   </cd-table>
 </ng-container>
 
index 6067a75ca2d189f51fa45e724365b5de626981d6..369c9b96acd18392a4b8dd4309ba33f71866cad0 100644 (file)
@@ -8,7 +8,11 @@
           (fetchData)="listNamespaces()"
           [columns]="namespacesColumns"
           selectionType="single"
-          (updateSelection)="updateSelection($event)">
+          (updateSelection)="updateSelection($event)"
+          emptyStateTitle="No namespaces created."
+          i18n-emptyStateTitle
+          emptyStateMessage="Namespaces are storage volumes mapped to subsystems for host access. Create a namespace to start provisioning storage within a subsystem."
+          i18n-emptyStateMessage>
 
   <div class="table-actions">
     <cd-table-actions [permission]="permission"
index 6d17f365350a6cc8aede6adcf03524466ffbe7a0..84a1c8763b1b1c7d2b0f32bff5cf482d885dd374 100644 (file)
           selectionType="single"
           [hasDetails]="true"
           (setExpandedRow)="setExpandedRow($event)"
-          (updateSelection)="updateSelection($event)">
+          (updateSelection)="updateSelection($event)"
+          emptyStateTitle="No subsystems created"
+          i18n-emptyStateTitle
+          emptyStateMessage="Subsystems group NVMe namespaces and manage host access. Create a subsystem to start mapping NVMe volumes to hosts."
+          i18n-emptyStateMessage>
 
   <div class="table-actions">
     <cd-table-actions [permission]="permissions.nvmeof"
@@ -43,4 +47,5 @@
                                 [group]="group">
   </cd-nvmeof-subsystems-details>
 </cd-table>
+
 <router-outlet name="modal"></router-outlet>
index 544c16f6a2429d01fd409bb12e71ed214568bc00..2024593ec224214048a56f65a063324c892e0b5d 100644 (file)
@@ -38,3 +38,7 @@ Using `color` in css and seyting svg will fill="currentColor does not work.
 .info-icon {
   fill: theme.$support-info !important;
 }
+
+.deploy-icon {
+  fill: theme.$layer-selected-disabled !important;
+}
index 8df7b98b69d2b8fcc47d10c03876a334f445428d..456763d3b104b0910ae2ce9b77b5250585d22070 100644 (file)
@@ -17,7 +17,8 @@ import {
   TagModule,
   LayerModule,
   InputModule,
-  GridModule
+  GridModule,
+  LayoutModule
 } from 'carbon-components-angular';
 import AddIcon from '@carbon/icons/es/add/16';
 import FilterIcon from '@carbon/icons/es/filter/16';
@@ -29,6 +30,7 @@ import MaximizeIcon from '@carbon/icons/es/maximize/16';
 import ArrowDown from '@carbon/icons/es/caret--down/16';
 import ChevronDwon from '@carbon/icons/es/chevron--down/16';
 import CheckMarkIcon from '@carbon/icons/es/checkmark/32';
+import CubeIcon from '@carbon/icons/es/cube/32';
 
 import { FormsModule, ReactiveFormsModule } from '@angular/forms';
 import { FormlyModule } from '@ngx-formly/core';
@@ -104,7 +106,8 @@ import { TableDetailDirective } from './directives/table-detail.directive';
     TagModule,
     LayerModule,
     InputModule,
-    GridModule
+    GridModule,
+    LayoutModule
   ],
   declarations: [
     TableComponent,
@@ -144,7 +147,8 @@ export class DataTableModule {
       MaximizeIcon,
       ArrowDown,
       ChevronDwon,
-      CheckMarkIcon
+      CheckMarkIcon,
+      CubeIcon
     ]);
   }
 }
index 2893f59cc93002f2729092fc8cd54dd4ed71150b..81b63d35d417381a2b60869b621cf8e7fbffc996 100644 (file)
           class="no-data"
           cdstabledata
           [attr.colspan]="visibleColumns.length + 2">
-        <span class="d-flex justify-content-center align-items-center"
-              i18n>No data to display</span>
+        <div class="empty-state cds-ml-3"
+             cdsStack="vertical"
+             gap="11">
+          <div></div>
+          <div cdsStack="vertical"
+               gap="1">
+            <div>
+              <cd-icon
+                [type]="emptyStateIcon"
+                [size]="iconSize.size32">
+              </cd-icon>
+            </div>
+            <legend class="cds--type-body-compact-02">
+              <ng-container>{{ emptyStateTitle }}</ng-container>
+              <cd-help-text class="cds--type-label-01">
+                {{ emptyStateMessage }}
+              </cd-help-text>
+            </legend>
+          </div>
+        </div>
       </td>
     </tr>
   </tbody>
     </cds-tag>
   </span>
 </ng-template>
+
 <ng-template #tagTpl
              let-column="data.column"
              let-value="data.value">
index 9ac507fae22d806556e904ddd3e9ae3de1d0e58f..30edd6a6ec4f1f95923fa63a1ad96996c6f2edad 100644 (file)
@@ -22,7 +22,8 @@ import { BehaviorSubject, Observable, of, Subject, Subscription } from 'rxjs';
 
 import { TableStatus } from '~/app/shared/classes/table-status';
 import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
-import { Icons } from '~/app/shared/enum/icons.enum';
+import { Icons, IconSize, ICON_TYPE } from '~/app/shared/enum/icons.enum';
+
 import { CdTableColumn } from '~/app/shared/models/cd-table-column';
 import { CdTableColumnFilter } from '~/app/shared/models/cd-table-column-filter';
 import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
@@ -226,6 +227,22 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr
   @Input()
   scrollable: boolean = true;
 
+  /**
+   * Title to be displayed when there is no data
+   */
+  @Input()
+  emptyStateTitle: string = $localize`No data available`;
+  /**
+   * Helper text to be displayed when there is no data
+   */
+  @Input()
+  emptyStateMessage: string = $localize`There are currently no records to display.`;
+  /**
+   * Icon to be displayed when there is no data
+   */
+  @Input()
+  emptyStateIcon: string = ICON_TYPE.deploy;
+
   /**
    * Should be a function to update the input data if undefined nothing will be triggered
    *
@@ -363,6 +380,7 @@ export class TableComponent implements AfterViewInit, OnInit, OnChanges, OnDestr
   }
 
   icons = Icons;
+  iconSize = IconSize;
   cellTemplates: {
     [key: string]: TemplateRef<any>;
   } = {};
index 50db9d77e826cb81a5000ebfc871943d0032859c..5f45acf054e62af07a5f7635f5624ebe90e45df1 100644 (file)
@@ -116,6 +116,7 @@ export const ICON_TYPE = {
   check: 'check',
   copy: 'copy',
   danger: 'danger',
+  deploy: 'deploy',
   edit: 'edit',
   error: 'error--filled',
   infoCircle: 'info-circle',