Shivam Mishra
2024-10-02 13:06:30 +05:30
committed by GitHub
parent e0bf2bd9d4
commit 42f6621afb
661 changed files with 15939 additions and 31194 deletions

View File

@@ -0,0 +1,24 @@
<script setup>
import { useMapGetter } from 'dashboard/composables/store';
defineProps({
content: {
type: String,
default: '',
},
});
const isRTL = useMapGetter('accounts/isRTL');
</script>
<template>
<div
class="overflow-hidden whitespace-nowrap text-ellipsis"
:class="{ 'text-right': isRTL }"
>
<slot v-if="$slots.default || content">
<template v-if="content">{{ content }}</template>
</slot>
<span v-else class="text-slate-300 dark:text-slate-700"> --- </span>
</div>
</template>

View File

@@ -0,0 +1,117 @@
<script setup>
import { computed } from 'vue';
const props = defineProps({
table: {
type: Object,
required: true,
},
});
const getFormattedPages = (start, end) => {
const formatter = new Intl.NumberFormat(navigator.language);
return Array.from({ length: end - start + 1 }, (_, i) =>
formatter.format(start + i)
);
};
const currentPage = computed(() => {
return props.table.getState().pagination.pageIndex + 1;
});
const totalPages = computed(() => {
return props.table.getPageCount();
});
const visiblePages = computed(() => {
if (totalPages.value <= 3) return getFormattedPages(1, totalPages.value);
if (currentPage.value === 1) return getFormattedPages(1, 3);
if (currentPage.value === totalPages.value) {
return getFormattedPages(totalPages.value - 2, totalPages.value);
}
return getFormattedPages(currentPage.value - 1, currentPage.value + 1);
});
const total = computed(() => {
return props.table.getRowCount();
});
const start = computed(() => {
const { pagination } = props.table.getState();
return pagination.pageIndex * pagination.pageSize + 1;
});
const end = computed(() => {
const { pagination } = props.table.getState();
return Math.min(
(pagination.pageIndex + 1) * pagination.pageSize,
total.value
);
});
</script>
<template>
<div class="flex items-center justify-between">
<div class="flex flex-1 items-center justify-between">
<div>
<p class="text-sm text-gray-700">
{{ $t('REPORT.PAGINATION.RESULTS', { start, end, total }) }}
</p>
</div>
<nav class="isolate inline-flex gap-1">
<woot-button
:disabled="!table.getCanPreviousPage()"
variant="clear"
class="size-8 flex items-center border border-slate-50"
color-scheme="secondary"
@click="table.setPageIndex(0)"
>
<span class="i-lucide-chevrons-left size-3" aria-hidden="true" />
</woot-button>
<woot-button
variant="clear"
class="size-8 flex items-center border border-slate-50"
color-scheme="secondary"
:disabled="!table.getCanPreviousPage()"
@click="table.previousPage()"
>
<span class="i-lucide-chevron-left size-3" aria-hidden="true" />
</woot-button>
<woot-button
v-for="page in visiblePages"
:key="page"
variant="clear"
class="size-8 flex items-center justify-center border text-xs leading-none text-center"
:class="page == currentPage ? 'border-woot-500' : 'border-slate-50'"
color-scheme="secondary"
@click="table.setPageIndex(page - 1)"
>
<div
class="text-center"
:class="{ 'text-woot-500': page == currentPage }"
>
{{ page }}
</div>
</woot-button>
<woot-button
:disabled="!table.getCanNextPage()"
variant="clear"
class="size-8 flex items-center border border-slate-50"
color-scheme="secondary"
@click="table.nextPage()"
>
<span class="i-lucide-chevron-right size-3" aria-hidden="true" />
</woot-button>
<woot-button
:disabled="!table.getCanNextPage()"
variant="clear"
class="size-8 flex items-center border border-slate-50"
color-scheme="secondary"
@click="table.setPageIndex(table.getPageCount() - 1)"
>
<span class="i-lucide-chevrons-right size-3" aria-hidden="true" />
</woot-button>
</nav>
</div>
</div>
</template>

View File

@@ -0,0 +1,18 @@
<script setup>
defineProps({
header: {
type: Object,
required: true,
},
});
const sortIconMap = {
default: 'i-lucide-chevrons-up-down',
asc: 'i-lucide-chevron-up',
desc: 'i-lucide-chevron-down',
};
</script>
<template>
<span :class="sortIconMap[header.column.getIsSorted() || 'default']" />
</template>

View File

@@ -0,0 +1,65 @@
<script setup>
import { FlexRender } from '@tanstack/vue-table';
import SortButton from './SortButton.vue';
defineProps({
table: {
type: Object,
required: true,
},
fixed: {
type: Boolean,
default: false,
},
});
</script>
<template>
<table :class="{ 'table-fixed': fixed }">
<thead
class="sticky top-0 z-10 border-b border-slate-50 dark:border-slate-800 bg-slate-25 dark:bg-slate-800"
>
<tr v-for="headerGroup in table.getHeaderGroups()" :key="headerGroup.id">
<th
v-for="header in headerGroup.headers"
:key="header.id"
:style="{
width: `${header.getSize()}px`,
}"
class="text-left py-3 px-5 dark:bg-slate-800 text-slate-800 dark:text-slate-200 font-normal text-xs"
@click="header.column.getCanSort() && header.column.toggleSorting()"
>
<div
v-if="!header.isPlaceholder"
class="flex place-items-center gap-1"
>
<FlexRender
:render="header.column.columnDef.header"
:props="header.getContext()"
/>
<SortButton v-if="header.column.getCanSort()" :header="header" />
</div>
</th>
</tr>
</thead>
<tbody class="divide-y divide-slate-25 dark:divide-slate-900">
<tr
v-for="row in table.getRowModel().rows"
:key="row.id"
class="hover:bg-slate-25 dark:hover:bg-slate-800"
>
<td
v-for="cell in row.getVisibleCells()"
:key="cell.id"
class="py-2 px-5"
>
<FlexRender
:render="cell.column.columnDef.cell"
:props="cell.getContext()"
/>
</td>
</tr>
</tbody>
</table>
</template>