ソースを参照

feat(newtab): add pagination for logs

Ahmad Kholid 3 年 前
コミット
7fe86ebd57
2 ファイル変更121 行追加1 行削除
  1. 94 0
      src/components/ui/UiPagination.vue
  2. 27 1
      src/newtab/pages/logs.vue

+ 94 - 0
src/components/ui/UiPagination.vue

@@ -0,0 +1,94 @@
+<template>
+  <div class="flex items-center">
+    <ui-button
+      v-tooltip="'Previous page'"
+      icon
+      @click="updatePage(modelValue - 1)"
+    >
+      <v-remixicon name="riArrowLeftSLine" />
+    </ui-button>
+    <div class="mx-4">
+      <input
+        ref="inputEl"
+        v-tooltip="'Current page'"
+        :value="modelValue"
+        :max="maxPage"
+        min="0"
+        class="
+          p-2
+          text-center
+          transition
+          w-10
+          appearance-none
+          bg-input
+          rounded-lg
+        "
+        type="number"
+        @click="$event.target.select()"
+        @input="updatePage(+$event.target.value, $event.target)"
+      />
+      of
+      {{ maxPage }}
+    </div>
+    <ui-button v-tooltip="'Next page'" icon @click="updatePage(modelValue + 1)">
+      <v-remixicon rotate="180" name="riArrowLeftSLine" />
+    </ui-button>
+  </div>
+</template>
+<script setup>
+import { computed, ref, watch } from 'vue';
+
+const props = defineProps({
+  modelValue: {
+    type: Number,
+    default: 1,
+  },
+  records: {
+    type: Number,
+    default: 10,
+  },
+  perPage: {
+    type: Number,
+    default: 10,
+  },
+});
+const emit = defineEmits(['update:modelValue', 'paginate']);
+
+const inputEl = ref(null);
+
+const maxPage = computed(() => Math.round(props.records / props.perPage));
+
+function emitEvent(page) {
+  emit('update:modelValue', page);
+  emit('paginate', page);
+}
+function updatePage(page, element) {
+  let currentPage = page;
+
+  if (currentPage > maxPage.value || currentPage < 1) {
+    if (!element) return;
+
+    currentPage = currentPage > maxPage.value ? maxPage.value : 1;
+  }
+
+  emitEvent(currentPage);
+}
+
+watch(
+  () => [props.perPage, props.records],
+  () => {
+    emitEvent(1);
+  }
+);
+</script>
+<style scoped>
+input::-webkit-outer-spin-button,
+input::-webkit-inner-spin-button {
+  -webkit-appearance: none;
+  margin: 0;
+}
+
+input[type='number'] {
+  -moz-appearance: textfield;
+}
+</style>

+ 27 - 1
src/newtab/pages/logs.vue

@@ -39,6 +39,22 @@
         </td>
         </td>
       </template>
       </template>
     </shared-logs-table>
     </shared-logs-table>
+    <div class="flex items-center justify-between mt-4">
+      <div>
+        Showing
+        <select v-model="pagination.perPage" class="p-1 rounded-md bg-input">
+          <option v-for="num in [10, 15, 25, 50, 100]" :key="num" :value="num">
+            {{ num }}
+          </option>
+        </select>
+        items out of {{ filteredLogs.length }}
+      </div>
+      <ui-pagination
+        v-model="pagination.currentPage"
+        :per-page="pagination.perPage"
+        :records="filteredLogs.length"
+      />
+    </div>
     <ui-card
     <ui-card
       v-if="selectedLogs.length !== 0"
       v-if="selectedLogs.length !== 0"
       class="fixed right-0 bottom-0 m-5 shadow-xl space-x-2"
       class="fixed right-0 bottom-0 m-5 shadow-xl space-x-2"
@@ -73,6 +89,10 @@ const store = useStore();
 const dialog = useDialog();
 const dialog = useDialog();
 
 
 const selectedLogs = ref([]);
 const selectedLogs = ref([]);
+const pagination = shallowReactive({
+  perPage: 10,
+  currentPage: 1,
+});
 const filtersBuilder = shallowReactive({
 const filtersBuilder = shallowReactive({
   query: '',
   query: '',
   byDate: 0,
   byDate: 0,
@@ -87,7 +107,7 @@ const exportDataModal = shallowReactive({
   log: {},
   log: {},
 });
 });
 
 
-const logs = computed(() =>
+const filteredLogs = computed(() =>
   Log.query()
   Log.query()
     .where(({ name, status, startedAt }) => {
     .where(({ name, status, startedAt }) => {
       let statusFilter = true;
       let statusFilter = true;
@@ -111,6 +131,12 @@ const logs = computed(() =>
     .orderBy(sortsBuilder.by, sortsBuilder.order)
     .orderBy(sortsBuilder.by, sortsBuilder.order)
     .get()
     .get()
 );
 );
+const logs = computed(() =>
+  filteredLogs.value.slice(
+    (pagination.currentPage - 1) * pagination.perPage,
+    pagination.currentPage * pagination.perPage
+  )
+);
 
 
 function deleteLog(id) {
 function deleteLog(id) {
   Log.delete(id).then(() => {
   Log.delete(id).then(() => {