diff --git a/pages/dashboard/index.vue b/pages/dashboard/index.vue index ae5c346..0d3ed4e 100644 --- a/pages/dashboard/index.vue +++ b/pages/dashboard/index.vue @@ -398,65 +398,6 @@ onMounted(() => { - - - - - - diff --git a/pages/form-builder/manage.vue b/pages/form-builder/manage.vue index de2100d..7759beb 100644 --- a/pages/form-builder/manage.vue +++ b/pages/form-builder/manage.vue @@ -125,7 +125,7 @@
@@ -204,8 +204,126 @@
+ +
+
+ +
+ Showing {{ paginationInfo.start }}-{{ paginationInfo.end }} of {{ paginationInfo.total }} forms +
+ + +
+ Items per page: + +
+ + +
+ + + + + + + + + +
+
+
+ -
+

{{ hasActiveFilters ? 'No forms match your filters' : 'No forms found' }} @@ -437,6 +555,11 @@ const jsonContent = ref(''); const jsonValidationMessage = ref(''); const jsonIsValid = ref(false); +// Pagination state +const currentPage = ref(1); +const itemsPerPage = ref(5); // Set to 5 to test pagination +const totalItems = ref(0); + // Computed properties for grouping const categoryOptions = computed(() => { const categories = [...new Set(formStore.savedForms.map(form => form.category).filter(Boolean))]; @@ -458,7 +581,7 @@ const hasActiveFilters = computed(() => { return searchQuery.value || selectedCategory.value || selectedGroup.value; }); -// Filtered forms +// Filtered forms (all forms after applying filters) const filteredForms = computed(() => { let filtered = formStore.savedForms; @@ -482,9 +605,42 @@ const filteredForms = computed(() => { filtered = filtered.filter(form => form.group === selectedGroup.value); } + // Update total items for pagination + totalItems.value = filtered.length; + return filtered; }); +// Paginated forms (forms for current page) +const paginatedForms = computed(() => { + const start = (currentPage.value - 1) * itemsPerPage.value; + const end = start + itemsPerPage.value; + return filteredForms.value.slice(start, end); +}); + +// Pagination computed properties +const totalPages = computed(() => { + return Math.ceil(totalItems.value / itemsPerPage.value); +}); + +const hasNextPage = computed(() => { + return currentPage.value < totalPages.value; +}); + +const hasPrevPage = computed(() => { + return currentPage.value > 1; +}); + +const paginationInfo = computed(() => { + const start = totalItems.value === 0 ? 0 : (currentPage.value - 1) * itemsPerPage.value + 1; + const end = Math.min(currentPage.value * itemsPerPage.value, totalItems.value); + return { + start, + end, + total: totalItems.value + }; +}); + // Format date for display const formatDate = (isoString) => { if (!isoString) return ''; @@ -623,6 +779,8 @@ onMounted(async () => { // Watch for changes in search and filters watch([searchQuery, selectedCategory, selectedGroup], () => { + // Reset to first page when filters change + currentPage.value = 1; // Debounce the search to avoid too many API calls clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { @@ -637,9 +795,34 @@ const clearFilters = () => { searchQuery.value = ''; selectedCategory.value = ''; selectedGroup.value = ''; + currentPage.value = 1; // Reset to first page // loadForms will be called automatically by the watcher }; +// Pagination methods +const goToPage = (page) => { + if (page >= 1 && page <= totalPages.value) { + currentPage.value = page; + } +}; + +const nextPage = () => { + if (hasNextPage.value) { + currentPage.value++; + } +}; + +const prevPage = () => { + if (hasPrevPage.value) { + currentPage.value--; + } +}; + +const changeItemsPerPage = (newItemsPerPage) => { + itemsPerPage.value = newItemsPerPage; + currentPage.value = 1; // Reset to first page when changing items per page +}; + // Helper function to get category color const getCategoryColor = (category) => { const colors = { diff --git a/pages/process-builder/manage.vue b/pages/process-builder/manage.vue index 9f6cb8d..526a3fc 100644 --- a/pages/process-builder/manage.vue +++ b/pages/process-builder/manage.vue @@ -29,6 +29,11 @@ const sortBy = ref('processCreatedDate'); const sortOrder = ref('desc'); const currentView = ref('dashboard'); // 'dashboard', 'list', 'analytics' +// Pagination state +const currentPage = ref(1); +const itemsPerPage = ref(5); // Set to 5 to test pagination +const totalItems = ref(0); + // Dashboard metrics and data const dashboardMetrics = ref({ totalProcesses: 0, @@ -66,9 +71,44 @@ const categoryOptions = [ { value: 'Procurement', label: 'Procurement' } ]; -// Filtered processes +// Filtered processes (all processes after applying filters) const filteredProcesses = computed(() => { - return processStore.processes; + let filtered = processStore.processes; + + // Update total items for pagination + totalItems.value = filtered.length; + + return filtered; +}); + +// Paginated processes (processes for current page) +const paginatedProcesses = computed(() => { + const start = (currentPage.value - 1) * itemsPerPage.value; + const end = start + itemsPerPage.value; + return filteredProcesses.value.slice(start, end); +}); + +// Pagination computed properties +const totalPages = computed(() => { + return Math.ceil(totalItems.value / itemsPerPage.value); +}); + +const hasNextPage = computed(() => { + return currentPage.value < totalPages.value; +}); + +const hasPrevPage = computed(() => { + return currentPage.value > 1; +}); + +const paginationInfo = computed(() => { + const start = totalItems.value === 0 ? 0 : (currentPage.value - 1) * itemsPerPage.value + 1; + const end = Math.min(currentPage.value * itemsPerPage.value, totalItems.value); + return { + start, + end, + total: totalItems.value + }; }); // Load dashboard summary data from API @@ -220,6 +260,8 @@ const loadProcesses = async () => { // Watch for changes in filters and reload processes watch([searchQuery, statusFilter, categoryFilter], () => { + // Reset to first page when filters change + currentPage.value = 1; clearTimeout(searchTimeout); searchTimeout = setTimeout(() => { loadProcesses(); @@ -349,6 +391,31 @@ const clearFilters = () => { searchQuery.value = ''; statusFilter.value = ''; categoryFilter.value = ''; + currentPage.value = 1; // Reset to first page +}; + +// Pagination methods +const goToPage = (page) => { + if (page >= 1 && page <= totalPages.value) { + currentPage.value = page; + } +}; + +const nextPage = () => { + if (hasNextPage.value) { + currentPage.value++; + } +}; + +const prevPage = () => { + if (hasPrevPage.value) { + currentPage.value--; + } +}; + +const changeItemsPerPage = (newItemsPerPage) => { + itemsPerPage.value = newItemsPerPage; + currentPage.value = 1; // Reset to first page when changing items per page }; // Load processes on component mount @@ -653,8 +720,9 @@ const copyWorkflowLink = async (processId) => {
+
@@ -774,8 +842,126 @@ const copyWorkflowLink = async (processId) => {
+ +
+
+ +
+ Showing {{ paginationInfo.start }}-{{ paginationInfo.end }} of {{ paginationInfo.total }} processes +
+ + +
+ Items per page: + +
+ + +
+ + + + + + + + + +
+
+
+ -
+

{{ (searchQuery || statusFilter || categoryFilter) ? 'No processes match your filters' : 'No processes found' }}