Browse Source

feat(admin-ui): Show total items in datatables (#1580)

Martijn 3 years ago
parent
commit
e8e349c5f9

+ 1 - 1
docs/content/developer-guide/deployment.md

@@ -39,7 +39,7 @@ and you should expect to see `UTC` or `Etc/UTC`.
 For a production Vendure server, there are a few security-related points to consider when deploying:
 For a production Vendure server, there are a few security-related points to consider when deploying:
 
 
 * Set the [Superadmin credentials]({{< relref "auth-options" >}}#superadmincredentials) to something other than the default.
 * Set the [Superadmin credentials]({{< relref "auth-options" >}}#superadmincredentials) to something other than the default.
-* Disable introspection in the [ApiOptions]({{ relref "api-options" }}#introspection) (this option is available in v1.5+).
+* Disable introspection in the [ApiOptions]({{< relref "api-options" >}}#introspection) (this option is available in v1.5+).
 * Consider taking steps to harden your GraphQL APIs against DOS attacks. Use the [ApiOptions]({{< relref "api-options" >}}) to set up appropriate Express middleware for things like [request timeouts](https://github.com/expressjs/express/issues/3330) and [rate limits](https://www.npmjs.com/package/express-rate-limit). A tool such as [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) can be used to mitigate resource-intensive GraphQL queries. 
 * Consider taking steps to harden your GraphQL APIs against DOS attacks. Use the [ApiOptions]({{< relref "api-options" >}}) to set up appropriate Express middleware for things like [request timeouts](https://github.com/expressjs/express/issues/3330) and [rate limits](https://www.npmjs.com/package/express-rate-limit). A tool such as [graphql-query-complexity](https://github.com/slicknode/graphql-query-complexity) can be used to mitigate resource-intensive GraphQL queries. 
 * You may wish to restrict the Admin API to only be accessed from trusted IPs. This could be achieved for instance by configuring an nginx reverse proxy that sits in front of the Vendure server.
 * You may wish to restrict the Admin API to only be accessed from trusted IPs. This could be achieved for instance by configuring an nginx reverse proxy that sits in front of the Vendure server.
 * By default, Vendure uses auto-increment integer IDs as entity primary keys. While easier to work with in development, sequential primary keys can leak information such as the number of orders or customers in the system. For this reason you should consider using the [UuidIdStrategy]({{< relref "entity-id-strategy" >}}#uuididstrategy) for production.
 * By default, Vendure uses auto-increment integer IDs as entity primary keys. While easier to work with in development, sequential primary keys can leak information such as the number of orders or customers in the system. For this reason you should consider using the [UuidIdStrategy]({{< relref "entity-id-strategy" >}}#uuididstrategy) for production.

+ 3 - 0
packages/admin-ui/src/lib/core/src/shared/components/data-table/data-table.component.html

@@ -49,6 +49,9 @@
             [itemsPerPage]="itemsPerPage"
             [itemsPerPage]="itemsPerPage"
             (itemsPerPageChange)="itemsPerPageChange.emit($event)"
             (itemsPerPageChange)="itemsPerPageChange.emit($event)"
         ></vdr-items-per-page-controls>
         ></vdr-items-per-page-controls>
+        <div>
+            {{ 'common.total-items' | translate: { currentStart, currentEnd, totalItems } }}
+        </div>
 
 
         <vdr-pagination-controls
         <vdr-pagination-controls
             *ngIf="totalItems"
             *ngIf="totalItems"

+ 12 - 4
packages/admin-ui/src/lib/core/src/shared/components/data-table/data-table.component.ts

@@ -2,12 +2,11 @@ import {
     AfterContentInit,
     AfterContentInit,
     ChangeDetectionStrategy,
     ChangeDetectionStrategy,
     Component,
     Component,
-    ContentChild,
     ContentChildren,
     ContentChildren,
     EventEmitter,
     EventEmitter,
-    Input,
+    Input, OnChanges,
     Output,
     Output,
-    QueryList,
+    QueryList, SimpleChanges,
     TemplateRef,
     TemplateRef,
 } from '@angular/core';
 } from '@angular/core';
 import { PaginationService } from 'ngx-pagination';
 import { PaginationService } from 'ngx-pagination';
@@ -80,7 +79,7 @@ import { DataTableColumnComponent } from './data-table-column.component';
     changeDetection: ChangeDetectionStrategy.OnPush,
     changeDetection: ChangeDetectionStrategy.OnPush,
     providers: [PaginationService],
     providers: [PaginationService],
 })
 })
-export class DataTableComponent<T> implements AfterContentInit {
+export class DataTableComponent<T> implements AfterContentInit, OnChanges {
     @Input() items: T[];
     @Input() items: T[];
     @Input() itemsPerPage: number;
     @Input() itemsPerPage: number;
     @Input() currentPage: number;
     @Input() currentPage: number;
@@ -95,6 +94,8 @@ export class DataTableComponent<T> implements AfterContentInit {
     @ContentChildren(DataTableColumnComponent) columns: QueryList<DataTableColumnComponent>;
     @ContentChildren(DataTableColumnComponent) columns: QueryList<DataTableColumnComponent>;
     @ContentChildren(TemplateRef) templateRefs: QueryList<TemplateRef<any>>;
     @ContentChildren(TemplateRef) templateRefs: QueryList<TemplateRef<any>>;
     rowTemplate: TemplateRef<any>;
     rowTemplate: TemplateRef<any>;
+    currentStart: number;
+    currentEnd: number;
 
 
     ngAfterContentInit(): void {
     ngAfterContentInit(): void {
         this.rowTemplate = this.templateRefs.last;
         this.rowTemplate = this.templateRefs.last;
@@ -107,4 +108,11 @@ export class DataTableComponent<T> implements AfterContentInit {
             return index;
             return index;
         }
         }
     }
     }
+
+    ngOnChanges(changes: SimpleChanges) {
+        if (changes.items) {
+            this.currentStart = this.itemsPerPage * (this.currentPage - 1);
+            this.currentEnd = this.currentStart + changes.items.currentValue?.length;
+        }
+    }
 }
 }

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/cs.json

@@ -256,6 +256,7 @@
     "theme": "Motiv",
     "theme": "Motiv",
     "there-are-unsaved-changes": "Provedené změny nebyly uloženy. Přechod na jinou stránku způsobí ztrátu těchto změn.",
     "there-are-unsaved-changes": "Provedené změny nebyly uloženy. Přechod na jinou stránku způsobí ztrátu těchto změn.",
     "toggle-all": "Přepnout vše",
     "toggle-all": "Přepnout vše",
+    "total-items": "{currentStart} - {currentEnd} z {totalItems}",
     "update": "Aktualizovat",
     "update": "Aktualizovat",
     "updated-at": "Aktualizováno",
     "updated-at": "Aktualizováno",
     "username": "Uživatelské jméno",
     "username": "Uživatelské jméno",
@@ -680,4 +681,4 @@
     "job-result": "Výsledek úlohy",
     "job-result": "Výsledek úlohy",
     "job-state": "Stav úlohy"
     "job-state": "Stav úlohy"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/de.json

@@ -256,6 +256,7 @@
     "theme": "Theme",
     "theme": "Theme",
     "there-are-unsaved-changes": "Es gibt ungespeicherte Änderungen. Wenn Sie wechseln, gehen diese Änderungen verloren.",
     "there-are-unsaved-changes": "Es gibt ungespeicherte Änderungen. Wenn Sie wechseln, gehen diese Änderungen verloren.",
     "toggle-all": "",
     "toggle-all": "",
+    "total-items": "{currentStart} - {currentEnd} von {totalItems}",
     "update": "Aktualisieren",
     "update": "Aktualisieren",
     "updated-at": "Aktualisiert am",
     "updated-at": "Aktualisiert am",
     "username": "Benutzername",
     "username": "Benutzername",
@@ -680,4 +681,4 @@
     "job-result": "Job-Ergebnis",
     "job-result": "Job-Ergebnis",
     "job-state": "Job-Status"
     "job-state": "Job-Status"
   }
   }
-}
+}

+ 1 - 0
packages/admin-ui/src/lib/static/i18n-messages/en.json

@@ -256,6 +256,7 @@
     "theme": "Theme",
     "theme": "Theme",
     "there-are-unsaved-changes": "There are unsaved changes. Navigating away will cause these changes to be lost.",
     "there-are-unsaved-changes": "There are unsaved changes. Navigating away will cause these changes to be lost.",
     "toggle-all": "Toggle all",
     "toggle-all": "Toggle all",
+    "total-items": "{currentStart} - {currentEnd} of {totalItems}",
     "update": "Update",
     "update": "Update",
     "updated-at": "Updated at",
     "updated-at": "Updated at",
     "username": "Username",
     "username": "Username",

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/es.json

@@ -256,6 +256,7 @@
     "theme": "Tema",
     "theme": "Tema",
     "there-are-unsaved-changes": "Hay cambios sin guardar. Si sale de este sitio sus cambios se perderán.",
     "there-are-unsaved-changes": "Hay cambios sin guardar. Si sale de este sitio sus cambios se perderán.",
     "toggle-all": "Activar todo",
     "toggle-all": "Activar todo",
+    "total-items": "{currentStart} - {currentEnd} de {totalItems}",
     "update": "Actualizar",
     "update": "Actualizar",
     "updated-at": "Actualizado el",
     "updated-at": "Actualizado el",
     "username": "Nombre de usuario",
     "username": "Nombre de usuario",
@@ -680,4 +681,4 @@
     "job-result": "Resultado",
     "job-result": "Resultado",
     "job-state": "Estado"
     "job-state": "Estado"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/fr.json

@@ -256,6 +256,7 @@
     "theme": "Thème",
     "theme": "Thème",
     "there-are-unsaved-changes": "Il y a des changements non enregistrés. Naviguer ailleurs fera perdre ces changements.",
     "there-are-unsaved-changes": "Il y a des changements non enregistrés. Naviguer ailleurs fera perdre ces changements.",
     "toggle-all": "Cocher/décocher Tout",
     "toggle-all": "Cocher/décocher Tout",
+    "total-items": "{currentStart} - {currentEnd} de {totalItems}",
     "update": "Mettre à jour",
     "update": "Mettre à jour",
     "updated-at": "Mis à jour à",
     "updated-at": "Mis à jour à",
     "username": "Nom d'utilisateur",
     "username": "Nom d'utilisateur",
@@ -680,4 +681,4 @@
     "job-result": "Résultat de la tâche",
     "job-result": "Résultat de la tâche",
     "job-state": "Etat de la tâche"
     "job-state": "Etat de la tâche"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/it.json

@@ -256,6 +256,7 @@
     "theme": "Tema",
     "theme": "Tema",
     "there-are-unsaved-changes": "Ci sono modifiche non salvate. Lasciando questa pagina le modifiche andranno perse.",
     "there-are-unsaved-changes": "Ci sono modifiche non salvate. Lasciando questa pagina le modifiche andranno perse.",
     "toggle-all": "Cambia tutti",
     "toggle-all": "Cambia tutti",
+    "total-items": "{currentStart} - {currentEnd} di {totalItems}",
     "update": "Aggiorna",
     "update": "Aggiorna",
     "updated-at": "Aggiornare a",
     "updated-at": "Aggiornare a",
     "username": "Username",
     "username": "Username",
@@ -680,4 +681,4 @@
     "job-result": "Risultato operazione",
     "job-result": "Risultato operazione",
     "job-state": "Stato operazione"
     "job-state": "Stato operazione"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/pl.json

@@ -256,6 +256,7 @@
     "theme": "",
     "theme": "",
     "there-are-unsaved-changes": "Są nie zapisane zmiany. Nawigacja do innej lokalizacji spowoduje utrate zmian.",
     "there-are-unsaved-changes": "Są nie zapisane zmiany. Nawigacja do innej lokalizacji spowoduje utrate zmian.",
     "toggle-all": "",
     "toggle-all": "",
+    "total-items": "{currentStart} - {currentEnd} z {totalItems}",
     "update": "Aktualizuj",
     "update": "Aktualizuj",
     "updated-at": "Zaaktualizowano dnia",
     "updated-at": "Zaaktualizowano dnia",
     "username": "Nazwa użytkownika",
     "username": "Nazwa użytkownika",
@@ -680,4 +681,4 @@
     "job-result": "Rezultat zlecenia",
     "job-result": "Rezultat zlecenia",
     "job-state": "Status zlecenia"
     "job-state": "Status zlecenia"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/pt_BR.json

@@ -256,6 +256,7 @@
     "theme": "Tema",
     "theme": "Tema",
     "there-are-unsaved-changes": "Há alterações não salvas. Navegar para outra página fará com que essas alterações sejam perdidas.",
     "there-are-unsaved-changes": "Há alterações não salvas. Navegar para outra página fará com que essas alterações sejam perdidas.",
     "toggle-all": "Alternar tudo",
     "toggle-all": "Alternar tudo",
+    "total-items": "{currentStart} - {currentEnd} de {totalItems}",
     "update": "Atualização",
     "update": "Atualização",
     "updated-at": "Atualizado em",
     "updated-at": "Atualizado em",
     "username": "Nome do usuário",
     "username": "Nome do usuário",
@@ -680,4 +681,4 @@
     "job-result": "Resultado do trabalho",
     "job-result": "Resultado do trabalho",
     "job-state": "Estado do trabalho"
     "job-state": "Estado do trabalho"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/pt_PT.json

@@ -256,6 +256,7 @@
     "theme": "Tema",
     "theme": "Tema",
     "there-are-unsaved-changes": "Há alterações por guardar. Navegar para outra página fará com que essas alterações sejam perdidas.",
     "there-are-unsaved-changes": "Há alterações por guardar. Navegar para outra página fará com que essas alterações sejam perdidas.",
     "toggle-all": "Alternar tudo",
     "toggle-all": "Alternar tudo",
+    "total-items": "{currentStart} - {currentEnd} de {totalItems}",
     "update": "Actualização",
     "update": "Actualização",
     "updated-at": "Actualizado em",
     "updated-at": "Actualizado em",
     "username": "Nome do utilizador",
     "username": "Nome do utilizador",
@@ -680,4 +681,4 @@
     "job-result": "Resultado do trabalho",
     "job-result": "Resultado do trabalho",
     "job-state": "Estado do trabalho"
     "job-state": "Estado do trabalho"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/ru.json

@@ -256,6 +256,7 @@
     "theme": "Тема",
     "theme": "Тема",
     "there-are-unsaved-changes": "Есть несохраненные изменения. Если вы выйдете, эти изменения будут потеряны.",
     "there-are-unsaved-changes": "Есть несохраненные изменения. Если вы выйдете, эти изменения будут потеряны.",
     "toggle-all": "Переключить все",
     "toggle-all": "Переключить все",
+    "total-items": "{currentStart} - {currentEnd} из {totalItems}",
     "update": "Обновить",
     "update": "Обновить",
     "updated-at": "Обновлено в",
     "updated-at": "Обновлено в",
     "username": "Имя пользователя",
     "username": "Имя пользователя",
@@ -680,4 +681,4 @@
     "job-result": "Результат задания",
     "job-result": "Результат задания",
     "job-state": "Состояние задания"
     "job-state": "Состояние задания"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/uk.json

@@ -256,6 +256,7 @@
     "theme": "Тема",
     "theme": "Тема",
     "there-are-unsaved-changes": "Є незбережені зміни. Якщо ви вийдете, ці зміни будуть втрачені.",
     "there-are-unsaved-changes": "Є незбережені зміни. Якщо ви вийдете, ці зміни будуть втрачені.",
     "toggle-all": "Переключити все",
     "toggle-all": "Переключити все",
+    "total-items": "{currentStart} - {currentEnd} з {totalItems}",
     "update": "Оновити",
     "update": "Оновити",
     "updated-at": "Оновлено в",
     "updated-at": "Оновлено в",
     "username": "Ім'я користувача",
     "username": "Ім'я користувача",
@@ -680,4 +681,4 @@
     "job-result": "Результат завдання",
     "job-result": "Результат завдання",
     "job-state": "Стан завдання"
     "job-state": "Стан завдання"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/zh_Hans.json

@@ -256,6 +256,7 @@
     "theme": "主题",
     "theme": "主题",
     "there-are-unsaved-changes": "修改尚未被保存,现在离开会导致您的修改会被删除",
     "there-are-unsaved-changes": "修改尚未被保存,现在离开会导致您的修改会被删除",
     "toggle-all": "全部切换",
     "toggle-all": "全部切换",
+    "total-items": "{currentStart} - {currentEnd} 的 {totalItems}",
     "update": "确认修改",
     "update": "确认修改",
     "updated-at": "修改时间",
     "updated-at": "修改时间",
     "username": "用户名",
     "username": "用户名",
@@ -680,4 +681,4 @@
     "job-result": "任务结果",
     "job-result": "任务结果",
     "job-state": "任务状态"
     "job-state": "任务状态"
   }
   }
-}
+}

+ 2 - 1
packages/admin-ui/src/lib/static/i18n-messages/zh_Hant.json

@@ -256,6 +256,7 @@
     "theme": "",
     "theme": "",
     "there-are-unsaved-changes": "變更尚未被儲存,離開會失去所有變更",
     "there-are-unsaved-changes": "變更尚未被儲存,離開會失去所有變更",
     "toggle-all": "",
     "toggle-all": "",
+    "total-items": "{currentStart} - {currentEnd} 的 {totalItems}",
     "update": "確認修改",
     "update": "確認修改",
     "updated-at": "修改時間",
     "updated-at": "修改時間",
     "username": "用户名",
     "username": "用户名",
@@ -680,4 +681,4 @@
     "job-result": "",
     "job-result": "",
     "job-state": ""
     "job-state": ""
   }
   }
-}
+}