Browse Source

[frontend] Add page number to Paginator component events

This also takes care of an issue where the Paginator emits updates for the same page under some circumstances
Johan Ahlen 4 years ago
parent
commit
cf1126d428

+ 1 - 0
desktop/core/src/desktop/js/components/Paginator.d.ts

@@ -15,6 +15,7 @@
 // limitations under the License.
 
 export interface Page {
+  pageNumber: number;
   offset: number;
   limit: number;
 }

+ 51 - 0
desktop/core/src/desktop/js/components/Paginator.scss

@@ -0,0 +1,51 @@
+/*
+ Licensed to Cloudera, Inc. under one
+ or more contributor license agreements.  See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership.  Cloudera, Inc. licenses this file
+ to you 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 'styles/colors';
+
+.hue-paginator {
+  width: 100%;
+  height: 25px;
+  text-align: right;
+  padding: 10px 0;
+
+  .page-status {
+    display: inline-block;
+    margin-right: 15px;
+  }
+
+  .navigation-actions {
+    a {
+      color: $fluid-gray-700;
+
+      &.disabled {
+        cursor: default;
+        color: $hue-action-disabled;
+      }
+
+      &:hover:not(.disabled) {
+        color: $hue-action-primary-hover;
+      }
+    }
+
+    font-size: 23px;
+    margin-left: 15px;
+    margin-right: 20px;
+    display: inline-block;
+  }
+}

+ 35 - 72
desktop/core/src/desktop/js/components/Paginator.vue

@@ -65,11 +65,13 @@
 </template>
 
 <script lang="ts">
-  import { defineComponent } from 'vue';
+  import { defineComponent, computed, ref } from 'vue';
 
+  import './Paginator.scss';
   import HueIcon from './HueIcon.vue';
   import DropdownMenu from './dropdown/DropdownMenu.vue';
   import DropdownMenuButton from './dropdown/DropdownMenuButton.vue';
+  import { Page } from './Paginator';
 
   const DEFAULT_LIMIT = 25;
   const PRESET_LIMITS = [DEFAULT_LIMIT, 50, 100];
@@ -77,70 +79,67 @@
   export default defineComponent({
     name: 'Paginator',
     components: {
-      HueIcon,
       DropdownMenu,
-      DropdownMenuButton
+      DropdownMenuButton,
+      HueIcon
     },
-
     props: {
       totalEntries: {
         type: Number,
         required: true
       }
     },
-
     emits: ['page-changed'],
-
-    setup(): {
-      presetLimits: number[];
-    } {
-      return {
-        presetLimits: PRESET_LIMITS
+    setup(props, { emit }) {
+      const currentPage = ref(1);
+      const limit = ref(DEFAULT_LIMIT);
+
+      const offset = computed(() => (currentPage.value - 1) * limit.value);
+
+      let lastNotifiedPage = undefined as Page | undefined;
+
+      const notifyPageChanged = (): void => {
+        if (
+          lastNotifiedPage?.offset !== offset.value ||
+          lastNotifiedPage.limit !== limit.value ||
+          lastNotifiedPage.pageNumber !== currentPage.value
+        ) {
+          lastNotifiedPage = {
+            pageNumber: currentPage.value,
+            offset: offset.value,
+            limit: limit.value
+          };
+          emit('page-changed', lastNotifiedPage);
+        }
       };
-    },
 
-    data(): {
-      currentPage: number;
-      limit: number;
-    } {
       return {
-        currentPage: 1,
-        limit: DEFAULT_LIMIT
+        currentPage,
+        limit,
+        offset,
+        notifyPageChanged,
+        presetLimits: PRESET_LIMITS
       };
     },
-
     computed: {
-      offset(): number {
-        return (this.currentPage - 1) * this.limit;
-      },
-
       lastDisplayedIndex(): number {
         return Math.min(this.offset + this.limit, this.totalEntries - 1);
       },
-
       totalPages(): number {
         return Math.ceil(this.totalEntries / this.limit) || 1;
       }
     },
-
     watch: {
-      currentPage(): void {
-        this.notifyPageChanged();
+      currentPage(newVal, oldVal): void {
+        if (newVal !== oldVal) {
+          this.notifyPageChanged();
+        }
       }
     },
-
     mounted(): void {
       this.notifyPageChanged();
     },
-
     methods: {
-      notifyPageChanged(): void {
-        this.$emit('page-changed', {
-          offset: this.offset,
-          limit: this.limit
-        });
-      },
-
       gotoFirstPage(): void {
         this.currentPage = 1;
       },
@@ -172,39 +171,3 @@
     }
   });
 </script>
-
-<style lang="scss" scoped>
-  @import 'styles/colors';
-
-  .hue-paginator {
-    width: 100%;
-    height: 25px;
-    text-align: right;
-    padding: 10px 0;
-
-    .page-status {
-      display: inline-block;
-      margin-right: 15px;
-    }
-
-    .navigation-actions {
-      a {
-        color: $fluid-gray-700;
-
-        &.disabled {
-          cursor: default;
-          color: $hue-action-disabled;
-        }
-
-        &:hover:not(.disabled) {
-          color: $hue-action-primary-hover;
-        }
-      }
-
-      font-size: 23px;
-      margin-left: 15px;
-      margin-right: 20px;
-      display: inline-block;
-    }
-  }
-</style>