From 9e0e454b3d890d36c0543ebf04a696bd80c41926 Mon Sep 17 00:00:00 2001
From: sajkar <sajjad.karimi@benify.com>
Date: Thu, 22 Aug 2024 13:10:28 +0200
Subject: [PATCH] feat: Add refresh button to the footer

---
 docs/api/table/inputs.md                      |  1 +
 .../lib/components/datatable.component.html   |  2 ++
 .../src/lib/components/datatable.component.ts | 30 ++++++++++++++++++-
 .../footer/footer.component.spec.ts           |  3 ++
 .../lib/components/footer/footer.component.ts | 11 +++++++
 .../lib/components/footer/footer.directive.ts |  1 +
 .../src/lib/themes/bootstrap.scss             | 22 ++++++++++++++
 .../ngx-datatable/src/lib/themes/dark.scss    | 22 ++++++++++++++
 .../src/lib/themes/material.scss              | 23 ++++++++++++++
 src/app/basic/responsive.component.ts         |  1 +
 src/app/basic/row-detail.component.ts         |  1 +
 src/app/basic/virtual.component.ts            |  1 +
 ...ng-scrolling-novirtualization.component.ts |  1 +
 src/app/paging/paging-server.component.ts     |  1 +
 src/app/paging/paging-virtual.component.ts    |  1 +
 .../summary-row-server-paging.component.ts    |  1 +
 src/assets/icons-reference.html               |  4 +++
 src/assets/icons.css                          |  4 +++
 18 files changed, 129 insertions(+), 1 deletion(-)

diff --git a/docs/api/table/inputs.md b/docs/api/table/inputs.md
index 4af5e8378..08579a549 100644
--- a/docs/api/table/inputs.md
+++ b/docs/api/table/inputs.md
@@ -30,6 +30,7 @@ pagerLeftArrow: 'datatable-icon-left',
 pagerRightArrow: 'datatable-icon-right',
 pagerPrevious: 'datatable-icon-prev',
 pagerNext: 'datatable-icon-skip'
+refresh: 'datatable-icon-refresh'
 ```
 
 ## `externalPaging`
diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html
index 2e0e39058..c4a9cdf31 100644
--- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html
+++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.html
@@ -78,7 +78,9 @@
     [selectedCount]="selected.length"
     [selectedMessage]="!!selectionType && messages.selectedMessage"
     [pagerNextIcon]="cssClasses.pagerNext"
+    [refreshIcon]="cssClasses.refresh"
     (page)="onFooterPage($event)"
+    (refresh)="onFooterRefresh($event)"
   >
   </datatable-footer>
 </div>
diff --git a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts
index 3cb20bed6..834136f4e 100644
--- a/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts
+++ b/projects/swimlane/ngx-datatable/src/lib/components/datatable.component.ts
@@ -309,7 +309,8 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit {
     pagerLeftArrow: 'datatable-icon-left',
     pagerRightArrow: 'datatable-icon-right',
     pagerPrevious: 'datatable-icon-prev',
-    pagerNext: 'datatable-icon-skip'
+    pagerNext: 'datatable-icon-skip',
+    refresh: 'datatable-icon-refresh'
   };
 
   /**
@@ -436,6 +437,11 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit {
    */
   @Output() page: EventEmitter<any> = new EventEmitter();
 
+  /**
+ * The table was refreshed
+ */
+  @Output() refresh: EventEmitter<any> = new EventEmitter();
+
   /**
    * Columns were re-ordered.
    */
@@ -919,6 +925,28 @@ export class DatatableComponent implements OnInit, DoCheck, AfterViewInit {
     }
   }
 
+    /**
+   * The footer triggered a refresh event.
+   */
+    onFooterRefresh(event: any) {
+      this.offset = event.page - 1;
+      this.bodyComponent.updateOffsetY(this.offset);
+  
+      this.refresh.emit({
+        count: this.count,
+        pageSize: this.pageSize,
+        limit: this.limit,
+        offset: this.offset
+      });
+  
+      if (this.selectAllRowsOnPage) {
+        this.selected = [];
+        this.select.emit({
+          selected: this.selected
+        });
+      }
+    }
+
   /**
    * Recalculates the sizes of the page
    */
diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts
index 497dfa403..40c4a8f5f 100644
--- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts
+++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.spec.ts
@@ -212,6 +212,7 @@ describe('DataTableFooterComponent', () => {
       [selectedCount]="selectedCount"
       [selectedMessage]="selectedMessage"
       [pagerNextIcon]="pagerNextIcon"
+      [refreshIcon]="refreshIcon"
       (page)="onPageEvent($event)"
     >
     </datatable-footer>
@@ -243,6 +244,7 @@ class TestFixtureComponent {
   pagerRightArrowIcon: string;
   pagerPreviousIcon: string;
   pagerNextIcon: string;
+  refreshIcon: string;
   totalMessage: string;
   footerTemplate: { template: TemplateRef<any> };
   selectedCount: number;
@@ -274,6 +276,7 @@ class DataTablePagerComponentMock {
   @Input() pagerRightArrowIcon: string;
   @Input() pagerPreviousIcon: string;
   @Input() pagerNextIcon: string;
+  @Input() refreshIcon: string;
   @Input() page: number;
   @Input() size: number;
   @Input() count: number;
diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts
index f742b6886..066b840ca 100644
--- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts
+++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.component.ts
@@ -23,6 +23,9 @@ import { DatatableFooterDirective } from './footer.directive';
       <div class="page-count" *ngIf="!footerTemplate">
         <span *ngIf="selectedMessage"> {{ selectedCount?.toLocaleString() }} {{ selectedMessage }} / </span>
         {{ rowCount?.toLocaleString() }} {{ totalMessage }}
+        <a role="button" aria-label="refresh" href="javascript:void(0)" (click)="reload()">
+          <i class="{{ refreshIcon }}"></i>
+        </a>
       </div>
       <datatable-pager
         *ngIf="!footerTemplate"
@@ -53,6 +56,7 @@ export class DataTableFooterComponent {
   @Input() pagerRightArrowIcon: string;
   @Input() pagerPreviousIcon: string;
   @Input() pagerNextIcon: string;
+  @Input() refreshIcon: string;
   @Input() totalMessage: string;
   @Input() footerTemplate: DatatableFooterDirective;
 
@@ -60,6 +64,13 @@ export class DataTableFooterComponent {
   @Input() selectedMessage: string | boolean;
 
   @Output() page: EventEmitter<any> = new EventEmitter();
+  @Output() refresh: EventEmitter<any> = new EventEmitter();
+
+  reload(): void {
+    this.refresh.emit({
+      page: this.curPage
+    })
+  }
 
   get isVisible(): boolean {
     return this.rowCount / this.pageSize > 1;
diff --git a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts
index ca807473c..76f27f680 100644
--- a/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts
+++ b/projects/swimlane/ngx-datatable/src/lib/components/footer/footer.directive.ts
@@ -10,6 +10,7 @@ export class DatatableFooterDirective {
   @Input() pagerRightArrowIcon: string;
   @Input() pagerPreviousIcon: string;
   @Input() pagerNextIcon: string;
+  @Input() refreshIcon: string;
 
   @Input('template')
   _templateInput: TemplateRef<any>;
diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss b/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss
index ee11271e6..600cb33ec 100644
--- a/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss
+++ b/projects/swimlane/ngx-datatable/src/lib/themes/bootstrap.scss
@@ -49,6 +49,26 @@ bootstrap table theme
       line-height: 50px;
       height: 50px;
       padding: 0 1.2rem;
+
+      a {
+        height: 22px;
+        min-width: 24px;
+        line-height: 22px;
+        padding: 4px 8px;
+        border-radius: 3px;
+        margin: 0 3px;
+        text-align: center;
+        vertical-align: top;
+        text-decoration: none;
+        vertical-align: middle;
+        color: #ededed;
+        font-size: 16px;
+
+        &:hover {
+            background-color: #545454;
+            font-weight: bold;
+        }
+      }
     }
     .datatable-pager {
       margin: 0 10px;
@@ -80,6 +100,8 @@ bootstrap table theme
         vertical-align: bottom;
         color: #ededed;
       }
+
+      .datatable-icon-refresh,
       .datatable-icon-left,
       .datatable-icon-skip,
       .datatable-icon-right,
diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss b/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss
index 8f0490ba9..c7f954c88 100644
--- a/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss
+++ b/projects/swimlane/ngx-datatable/src/lib/themes/dark.scss
@@ -59,6 +59,26 @@
       line-height: 50px;
       height: 50px;
       padding: 0 1.2rem;
+      
+      a {
+        height: 22px;
+        min-width: 24px;
+        line-height: 22px;
+        padding: 4px 8px;
+        border-radius: 3px;
+        margin: 0 3px;
+        text-align: center;
+        vertical-align: top;
+        text-decoration: none;
+        vertical-align: middle;
+        color: #72809b;
+        font-size: 16px;
+
+        &:hover {
+          background-color: #455066;
+          font-weight: bold;
+        }
+      }
     }
 
     .datatable-pager {
@@ -93,6 +113,8 @@
         color: #72809b;
       }
 
+      
+      .datatable-icon-refresh,
       .datatable-icon-left,
       .datatable-icon-skip,
       .datatable-icon-right,
diff --git a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss
index 3eccfd004..028d87bdb 100644
--- a/projects/swimlane/ngx-datatable/src/lib/themes/material.scss
+++ b/projects/swimlane/ngx-datatable/src/lib/themes/material.scss
@@ -344,6 +344,28 @@ $datatable-summary-row-background-hover: #ddd !default;
       line-height: 50px;
       height: 50px;
       padding: 0 1.2rem;
+
+
+      a {
+        height: 22px;
+        min-width: 24px;
+        line-height: 22px;
+        padding: 3px 12px;
+        border-radius: 3px;
+        margin: 6px 3px;
+        text-align: center;
+        vertical-align: top;
+        color: $datatable-pager-color;
+        text-decoration: none;
+        vertical-align: middle;
+        font-weight: bold;
+        font-size: 16px;
+
+        &:hover {
+          color: $datatable-pager-color-hover;
+          background-color: $datatable-pager-background-hover;
+        }
+      }
     }
 
     .datatable-pager {
@@ -382,6 +404,7 @@ $datatable-summary-row-background-hover: #ddd !default;
         }
       }
 
+      .datatable-icon-refresh,
       .datatable-icon-left,
       .datatable-icon-skip,
       .datatable-icon-right,
diff --git a/src/app/basic/responsive.component.ts b/src/app/basic/responsive.component.ts
index efba330c1..19ff6d73f 100644
--- a/src/app/basic/responsive.component.ts
+++ b/src/app/basic/responsive.component.ts
@@ -46,6 +46,7 @@ import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api';
         [scrollbarV]="true"
         [rows]="rows"
         (page)="onPage($event)"
+        (refresh)="onPage($event)"
       >
         <!-- Row Detail Template -->
         <ngx-datatable-row-detail [rowHeight]="50" #myDetailRow (toggle)="onDetailToggle($event)">
diff --git a/src/app/basic/row-detail.component.ts b/src/app/basic/row-detail.component.ts
index 9ed090a88..869133d4c 100644
--- a/src/app/basic/row-detail.component.ts
+++ b/src/app/basic/row-detail.component.ts
@@ -31,6 +31,7 @@ import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api';
         [scrollbarV]="true"
         [rows]="rows"
         (page)="onPage($event)"
+        (refresh)="onPage($event)"
       >
         <!-- Row Detail Template -->
         <ngx-datatable-row-detail [rowHeight]="100" #myDetailRow (toggle)="onDetailToggle($event)">
diff --git a/src/app/basic/virtual.component.ts b/src/app/basic/virtual.component.ts
index 92ff3ba4e..9538aed45 100644
--- a/src/app/basic/virtual.component.ts
+++ b/src/app/basic/virtual.component.ts
@@ -25,6 +25,7 @@ import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api';
         [rowHeight]="getRowHeight"
         [scrollbarV]="true"
         (page)="onPage($event)"
+        (refresh)="onPage($event)"
       >
         <ngx-datatable-column name="Name" [width]="300">
           <ng-template let-value="value" ngx-datatable-cell-template>
diff --git a/src/app/paging/paging-scrolling-novirtualization.component.ts b/src/app/paging/paging-scrolling-novirtualization.component.ts
index accf4cf2e..ed0480233 100644
--- a/src/app/paging/paging-scrolling-novirtualization.component.ts
+++ b/src/app/paging/paging-scrolling-novirtualization.component.ts
@@ -35,6 +35,7 @@ import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api';
         [offset]="page.pageNumber"
         [limit]="page.size"
         (page)="setPage($event)"
+        (refresh)="setPage($event)"
       >
       </ngx-datatable>
     </div>
diff --git a/src/app/paging/paging-server.component.ts b/src/app/paging/paging-server.component.ts
index 99f3ac3c0..7e770ed1c 100644
--- a/src/app/paging/paging-server.component.ts
+++ b/src/app/paging/paging-server.component.ts
@@ -33,6 +33,7 @@ import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api';
         [offset]="page.pageNumber"
         [limit]="page.size"
         (page)="setPage($event)"
+        (refresh)="setPage($event)"
       >
       </ngx-datatable>
     </div>
diff --git a/src/app/paging/paging-virtual.component.ts b/src/app/paging/paging-virtual.component.ts
index a668b1036..f290c5221 100644
--- a/src/app/paging/paging-virtual.component.ts
+++ b/src/app/paging/paging-virtual.component.ts
@@ -47,6 +47,7 @@ interface PageInfo {
         [count]="totalElements"
         [offset]="pageNumber"
         (page)="setPage($event)"
+        (refresh)="setPage($event)"
       >
       </ngx-datatable>
     </div>
diff --git a/src/app/summary/summary-row-server-paging.component.ts b/src/app/summary/summary-row-server-paging.component.ts
index c0a314714..9666dc1f5 100644
--- a/src/app/summary/summary-row-server-paging.component.ts
+++ b/src/app/summary/summary-row-server-paging.component.ts
@@ -35,6 +35,7 @@ import { ColumnMode } from 'projects/swimlane/ngx-datatable/src/public-api';
         [offset]="page.pageNumber"
         [limit]="page.size"
         (page)="setPage($event)"
+        (refresh)="setPage($event)"
       >
       </ngx-datatable>
     </div>
diff --git a/src/assets/icons-reference.html b/src/assets/icons-reference.html
index 77e719b8b..e10494f78 100644
--- a/src/assets/icons-reference.html
+++ b/src/assets/icons-reference.html
@@ -307,6 +307,10 @@ <h2>CSS mapping</h2>
           <div class="icon datatable-icon-prev"></div>
           <input type="text" readonly="readonly" value="prev" />
         </li>
+        <li>
+          <div class="icon datatable-icon-refresh"></div>
+          <input type="text" readonly="readonly" value="refresh" />
+        </li>
       </ul>
       <h2>Character mapping</h2>
       <ul class="glyphs character-mapping">
diff --git a/src/assets/icons.css b/src/assets/icons.css
index 77d30bf82..d03c50544 100644
--- a/src/assets/icons.css
+++ b/src/assets/icons.css
@@ -103,3 +103,7 @@
 .datatable-icon-prev::before {
   content: '\72';
 }
+
+.datatable-icon-refresh::before {
+  content: '\1F5D8';
+}