|
1 | 1 | <script setup lang="ts"> |
2 | | -import { computed } from 'vue'; |
| 2 | +import { computed, onMounted, ref, watch } from 'vue'; |
3 | 3 | import type { |
4 | 4 | CreateClientBody, |
5 | 5 | CreateProjectBody, |
@@ -38,6 +38,8 @@ const props = defineProps<{ |
38 | 38 | canCreateProject: boolean; |
39 | 39 | }>(); |
40 | 40 |
|
| 41 | +const maxVisibleGroups = ref(7); // Start with 10 day groups, then show all |
| 42 | +
|
41 | 43 | const groupedTimeEntries = computed(() => { |
42 | 44 | const groupedEntriesByDay: Record<string, TimeEntry[]> = {}; |
43 | 45 | for (const entry of props.timeEntries) { |
@@ -94,6 +96,7 @@ const groupedTimeEntries = computed(() => { |
94 | 96 |
|
95 | 97 | groupedEntriesByDayAndType[dailyEntriesKey] = newDailyEntries; |
96 | 98 | } |
| 99 | +
|
97 | 100 | return groupedEntriesByDayAndType; |
98 | 101 | }); |
99 | 102 |
|
@@ -134,11 +137,43 @@ function unselectAllTimeEntries(value: TimeEntriesGroupedByType[]) { |
134 | 137 | ); |
135 | 138 | }); |
136 | 139 | } |
| 140 | +
|
| 141 | +const visibleGroupedEntries = computed(() => { |
| 142 | + const allGroups = Object.entries(groupedTimeEntries.value); |
| 143 | + return Object.fromEntries(allGroups.slice(0, maxVisibleGroups.value)); |
| 144 | +}); |
| 145 | +
|
| 146 | +const totalGroups = computed(() => Object.keys(groupedTimeEntries.value).length); |
| 147 | +
|
| 148 | +function startProgressiveLoading() { |
| 149 | + const loadMoreGroups = () => { |
| 150 | + if (maxVisibleGroups.value < totalGroups.value) { |
| 151 | + maxVisibleGroups.value = Math.min(maxVisibleGroups.value + 5, totalGroups.value); |
| 152 | +
|
| 153 | + if (maxVisibleGroups.value < totalGroups.value) { |
| 154 | + requestIdleCallback(loadMoreGroups); |
| 155 | + } |
| 156 | + } |
| 157 | + }; |
| 158 | +
|
| 159 | + requestIdleCallback(loadMoreGroups); |
| 160 | +} |
| 161 | +
|
| 162 | +// Watch for changes to totalGroups and adjust maxVisibleGroups accordingly |
| 163 | +watch(totalGroups, (newTotal, oldTotal) => { |
| 164 | + if (newTotal !== oldTotal) { |
| 165 | + maxVisibleGroups.value = newTotal; |
| 166 | + } |
| 167 | +}); |
| 168 | +
|
| 169 | +onMounted(() => { |
| 170 | + startProgressiveLoading(); |
| 171 | +}); |
137 | 172 | </script> |
138 | 173 |
|
139 | 174 | <template> |
140 | 175 | <div class="@container"> |
141 | | - <div v-for="(value, key) in groupedTimeEntries" :key="key"> |
| 176 | + <div v-for="(value, key) in visibleGroupedEntries" :key="key"> |
142 | 177 | <TimeEntryRowHeading |
143 | 178 | :date="key" |
144 | 179 | :duration="sumDuration(value)" |
|
0 commit comments