Skip to content

Commit

Permalink
feat(statistic_preview): Read CSV from the back to display a table th…
Browse files Browse the repository at this point in the history
…at preview the content (#1455)
  • Loading branch information
NyraSama authored May 28, 2024
1 parent 6758ebf commit 5571595
Show file tree
Hide file tree
Showing 3 changed files with 204 additions and 0 deletions.
21 changes: 21 additions & 0 deletions yaki_admin/src/services/statistics.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,27 @@ class StatisticsService {
return "javascript:void(0)";
}
};

getStatisticsArray = async (
customerId: number,
teamId: number,
statisticType: STATISTICTYPE,
periodStart: string,
periodEnd: string,
): Promise<Array<Array<string>>> => {
const data = await this.getStatisticsCsv(
customerId,
teamId,
statisticType,
periodStart,
periodEnd,
);

const response = await fetch(data);
const csvText = await response.text();

return csvText.split("\n").map((row) => row.split(","));
};
}

export const statisticsService = Object.freeze(new StatisticsService());
159 changes: 159 additions & 0 deletions yaki_admin/src/ui/components/PreviewTable.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
<script setup lang="ts">
import { computed, ref } from "vue";
import chevronLeftIcon from "@/assets/icons_svg/Chevron-left.svg";
import chevronRightIcon from "@/assets/icons_svg/Chevron-right.svg";
//define the props
const props = defineProps({
statisticsArray: {
type: Array<Array<string>>,
required: true,
},
});
// Pagination variables
const currentPage = ref(1);
const rowsPerPage = 10;
// Computed property for pagination
const paginatedStatisticsArray = computed(() => {
// We get the start using the currentPage and rowsPerPage and we add 1 to ignore the first row (headers)
let start = 1 + (currentPage.value - 1) * rowsPerPage;
// We get the end using the start and rowsPerPage
let end = start + rowsPerPage;
// We filter the array to remove empty rows
return props.statisticsArray.slice(start, end).filter((row) => row[0] !== "" || row.length > 1);
});
// Methods for pagination
const nextPage = () => {
if (currentPage.value * rowsPerPage < props.statisticsArray.length) {
currentPage.value++;
}
};
const prevPage = () => {
if (currentPage.value > 1) {
currentPage.value--;
}
};
</script>

<template>
<table v-if="paginatedStatisticsArray.length && paginatedStatisticsArray[0][0] !== ''">
<thead>
<tr>
<th
v-for="header in props.statisticsArray[0]"
:key="header"
>
{{ header }}
</th>
</tr>
</thead>
<tbody>
<tr
v-for="(row, index) in paginatedStatisticsArray"
:key="index"
>
<td
v-for="(cell, index) in row"
:key="index"
>
{{ cell }}
</td>
</tr>
<!-- We fill the table with empty cells to always have the same size-->
<tr
v-for="index in rowsPerPage - paginatedStatisticsArray.length"
:key="index"
>
<td
v-for="index in props.statisticsArray[0].length"
:key="index"
style="opacity: 0"
>
''
</td>
</tr>
</tbody>
</table>
<section v-if="paginatedStatisticsArray.length && paginatedStatisticsArray[0][0] !== ''">
<button
@click="prevPage"
:style="currentPage === 1 ? 'pointer-events: none; opacity: 0.2;' : ''"
>
<figure>
<img
:src="chevronLeftIcon"
alt=""
/>
</figure>
</button>
<span
>Page : {{ currentPage }} / {{ Math.ceil((statisticsArray.length - 1) / rowsPerPage) }}</span
>
<button
@click="nextPage"
:style="
currentPage * rowsPerPage >= statisticsArray.length
? 'pointer-events: none; opacity: 0.2;'
: ''
"
>
<figure>
<img
:src="chevronRightIcon"
alt=""
/>
</figure>
</button>
</section>
</template>

<style scoped lang="scss">
table {
width: 100%;
border-collapse: collapse;
margin-top: 20px;
font-family: $font-sf-compact;
font-size: 11pt;
th,
td {
border: 1px solid #ddd;
padding: 8px;
text-align: left;
}
tr {
background-color: white;
&:nth-child(even) {
background-color: #f2f2f2;
}
}
th {
padding-top: 12px;
padding-bottom: 12px;
text-align: left;
background-color: $background-color-theme-secondary;
}
}
section {
width: 100%;
display: flex;
justify-content: center;
align-items: center;
gap: 1rem;
font-family: $font-rubik;
button {
border: none;
background-color: $background-color-theme-primary;
cursor: pointer;
}
}
</style>
24 changes: 24 additions & 0 deletions yaki_admin/src/ui/views/StatisticsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import PageContentHeader from "@/ui/components/PageContentHeader.vue";
import PageContentLayout from "@/ui/layouts/PageContentLayout.vue";
import buttonPrimary from "@/ui/components/buttons/ButtonPrimary.vue";
import PreviewTable from "@/ui/components/PreviewTable.vue";
import { statisticsService } from "@/services/statistics.service";
import { useSelectedRoleStore } from "@/stores/selectedRole";
Expand All @@ -24,6 +25,7 @@ const periodStartSelected = ref<string>(
new Date(Date.now() - 30 * 24 * 60 * 60 * 1000).toISOString().split("T")[0],
);
const periodEndSelected = ref<string>(new Date().toISOString().split("T")[0]);
const statisticsPreview = ref<Array<Array<string>>>([[""]]);
onMounted(() => {
if (roleStore.getCustomersIdWhereIgotRights.length === 0) {
Expand Down Expand Up @@ -60,26 +62,45 @@ const downloadCsv = async () => {
}
};
const loadPreview = async () => {
const customerId = selectedRoleStore.getCustomerIdSelected;
try {
statisticsPreview.value = await statisticsService.getStatisticsArray(
customerId,
teamSelected.value,
statisticTypeSelected.value,
periodStartSelected.value,
periodEndSelected.value,
);
} catch (error) {
console.error("Error while getting preview :", error);
}
};
const onSelectTeam = (e: Event) => {
teamSelected.value = parseInt((e.target as HTMLSelectElement).value);
loadPreview();
};
const onSelectStatisticType = (e: Event) => {
statisticTypeSelected.value = (e.target as HTMLSelectElement).value as STATISTICTYPE;
loadPreview();
};
const onSelectPeriodStart = (e: Event) => {
periodStartSelected.value = (e.target as HTMLInputElement).value;
if (new Date((e.target as HTMLInputElement).value) > new Date(periodEndSelected.value)) {
periodEndSelected.value = (e.target as HTMLInputElement).value;
}
loadPreview();
};
const onSelectPeriodEnd = (e: Event) => {
periodEndSelected.value = (e.target as HTMLInputElement).value;
if (new Date((e.target as HTMLInputElement).value) < new Date(periodStartSelected.value)) {
periodStartSelected.value = (e.target as HTMLInputElement).value;
}
loadPreview();
};
</script>

Expand Down Expand Up @@ -173,6 +194,9 @@ const onSelectPeriodEnd = (e: Event) => {
@click.prevent="downloadCsv"
/>
</section>
<section>
<PreviewTable :statisticsArray="statisticsPreview" />
</section>
</main>
</template>
</page-content-layout>
Expand Down

0 comments on commit 5571595

Please sign in to comment.