Refactor DepartmentLane.vue to use reusable ModuleActionLogsTable component
- Replaced inline logs table in `DepartmentLane.vue` with reusable `ModuleActionLogsTable` for better modularity. - Enhanced `ModuleActionLogs` to support pagination and dynamic filtering. - Introduced new `ModuleActionLogsTable.vue` component to centralize log display logic.
This commit is contained in:
@@ -0,0 +1,143 @@
|
||||
<script setup>
|
||||
import {computed, onMounted, ref, watch} from 'vue';
|
||||
import {SessionUser} from "@/components/session/token/SessionUser.vue";
|
||||
import PaginationNavigation from "@/components/displays/pagination/PaginationNavigation.vue";
|
||||
import PaginationDisplay from "@/components/displays/pagination/PaginationDisplay.vue";
|
||||
|
||||
const props = defineProps({
|
||||
module: {
|
||||
type: String,
|
||||
default: null
|
||||
},
|
||||
title: {
|
||||
type: String,
|
||||
default: 'Handlingslogs'
|
||||
}
|
||||
});
|
||||
|
||||
const logs = ref([]);
|
||||
const isLoading = ref(false);
|
||||
|
||||
// Pagination state
|
||||
const currentPage = ref(1);
|
||||
const itemsPerPage = ref(10);
|
||||
const totalItems = ref(0);
|
||||
|
||||
const totalPages = computed(() => {
|
||||
return Math.ceil(totalItems.value / itemsPerPage.value);
|
||||
});
|
||||
|
||||
const loadLogs = async () => {
|
||||
isLoading.value = true;
|
||||
try {
|
||||
const filters = {};
|
||||
if (props.module) {
|
||||
filters.module = props.module;
|
||||
}
|
||||
|
||||
const response = await SessionUser.objects.module_action_logs.get.all(
|
||||
filters,
|
||||
{ page: currentPage.value, limit: itemsPerPage.value, order: 'id:DESC' }
|
||||
);
|
||||
|
||||
// Based on the implementation in DepartmentLane.vue, we need to handle both raw array and paginated response
|
||||
if (response && response.data) {
|
||||
logs.value = response.data;
|
||||
if (response.meta && response.meta.pagination) {
|
||||
totalItems.value = response.meta.pagination.total;
|
||||
} else {
|
||||
totalItems.value = response.data.length;
|
||||
}
|
||||
} else {
|
||||
logs.value = response || [];
|
||||
totalItems.value = logs.value.length;
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Failed to load logs:", error);
|
||||
} finally {
|
||||
isLoading.value = false;
|
||||
}
|
||||
};
|
||||
|
||||
const setPage = (page) => {
|
||||
currentPage.value = page;
|
||||
loadLogs();
|
||||
};
|
||||
|
||||
const setItemsPerPage = (limit) => {
|
||||
itemsPerPage.value = limit;
|
||||
currentPage.value = 1;
|
||||
loadLogs();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
loadLogs();
|
||||
});
|
||||
|
||||
watch(() => props.module, () => {
|
||||
currentPage.value = 1;
|
||||
loadLogs();
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="box">
|
||||
<h3 class="title is-4">{{ title }}</h3>
|
||||
|
||||
<PaginationDisplay
|
||||
:metaItemsPerPage="itemsPerPage"
|
||||
:loadFunction="loadLogs"
|
||||
:isLoading="isLoading"
|
||||
:setMetaItemsPerPage="setItemsPerPage"
|
||||
/>
|
||||
|
||||
<div class="table-container">
|
||||
<table class="table is-fullwidth is-striped is-hoverable" :class="{ 'is-skeleton': isLoading }">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.created_at.label }}</th>
|
||||
<th v-if="!module">{{ SessionUser.objects.module_action_logs.columns.module.label }}</th>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.action.label }}</th>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.status_code.label }}</th>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.data.label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="log in logs" :key="log.id">
|
||||
<td>{{ new Date(log.created_at).toLocaleString() }}</td>
|
||||
<td v-if="!module">{{ log.module }}</td>
|
||||
<td>{{ log.action }}</td>
|
||||
<td>
|
||||
<span class="tag" :class="log.status_code >= 200 && log.status_code < 300 ? 'is-success' : 'is-danger'">
|
||||
{{ log.status_code }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<pre style="font-size: 0.75rem; max-height: 100px; overflow-y: auto;">{{ JSON.stringify(log.data, null, 2) }}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="logs.length === 0 && !isLoading">
|
||||
<td :colspan="module ? 4 : 5" class="has-text-centered">Ingen logs fundet</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<PaginationNavigation
|
||||
:currentPage="currentPage"
|
||||
:totalPages="totalPages"
|
||||
:setPage="setPage"
|
||||
:loadFunction="loadLogs"
|
||||
:isLoading="isLoading"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
pre {
|
||||
background-color: transparent;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
color: inherit;
|
||||
}
|
||||
</style>
|
||||
@@ -48,14 +48,10 @@ export const ModuleActionLogs = {
|
||||
}
|
||||
},
|
||||
get: {
|
||||
all: async (filters = {}) => {
|
||||
all: async (filters = {}, pagination = { page: 1, limit: 10, order: 'id:DESC' }) => {
|
||||
return ObjectsGlobal.get.list(ModuleActionLogs.meta.endpoint, {
|
||||
filters: filters,
|
||||
pagination: {
|
||||
page: 1,
|
||||
limit: 100,
|
||||
order: 'id:DESC'
|
||||
}
|
||||
pagination: pagination
|
||||
});
|
||||
},
|
||||
single: async (id) => {
|
||||
|
||||
@@ -1,17 +1,17 @@
|
||||
<script setup>
|
||||
import {onMounted, ref} from 'vue';
|
||||
import {computed, onMounted, ref} from 'vue';
|
||||
import {useRouter} from 'vue-router';
|
||||
import {SessionUser} from "@/components/session/token/SessionUser.vue";
|
||||
import RestrictedPageWrapper from "@/components/page/wrappers/RestrictedPageWrapper.vue";
|
||||
import SuperUserDashboardNavigation from "@/views/dashboards/superUserDashboard/SuperUserDashboardNavigation.vue";
|
||||
import PageTitle from "@/components/global/PageTitle.vue";
|
||||
import ModuleActionLogsTable from "@/components/displays/superuser/tables/ModuleActionLogsTable.vue";
|
||||
|
||||
const router = useRouter();
|
||||
const laneId = router.currentRoute.value.params.id;
|
||||
const lane = ref(null);
|
||||
const isLoading = ref(true);
|
||||
const departmentName = ref('');
|
||||
const logs = ref([]);
|
||||
|
||||
const loadLane = async () => {
|
||||
isLoading.value = true;
|
||||
@@ -20,7 +20,6 @@ const loadLane = async () => {
|
||||
SessionUser.objects.department_lanes.functions.getDepartmentName(lane.value.department).then(name => {
|
||||
departmentName.value = name;
|
||||
});
|
||||
logs.value = await SessionUser.objects.module_action_logs.get.all({module: 'selfserve'});
|
||||
} catch (error) {
|
||||
console.error("Failed to load lane:", error);
|
||||
} finally {
|
||||
@@ -128,38 +127,7 @@ onMounted(() => {
|
||||
|
||||
<div class="columns">
|
||||
<div class="column is-12">
|
||||
<div class="box">
|
||||
<h3 class="title is-4">Handlingslogs (selfserve)</h3>
|
||||
<div class="table-container">
|
||||
<table class="table is-fullwidth is-striped is-hoverable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.created_at.label }}</th>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.action.label }}</th>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.status_code.label }}</th>
|
||||
<th>{{ SessionUser.objects.module_action_logs.columns.data.label }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr v-for="log in logs" :key="log.id">
|
||||
<td>{{ new Date(log.created_at).toLocaleString() }}</td>
|
||||
<td>{{ log.action }}</td>
|
||||
<td>
|
||||
<span class="tag" :class="log.status_code >= 200 && log.status_code < 300 ? 'is-success' : 'is-danger'">
|
||||
{{ log.status_code }}
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<pre style="font-size: 0.75rem; max-height: 100px; overflow-y: auto;">{{ JSON.stringify(log.data, null, 2) }}</pre>
|
||||
</td>
|
||||
</tr>
|
||||
<tr v-if="logs.length === 0">
|
||||
<td colspan="4" class="has-text-centered">Ingen logs fundet</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<ModuleActionLogsTable module="selfserve" title="Handlingslogs (selfserve)" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user