diff --git a/frontend/src/components/Map.vue b/frontend/src/components/Map.vue
index 48637cb..79dc7c7 100644
--- a/frontend/src/components/Map.vue
+++ b/frontend/src/components/Map.vue
@@ -44,13 +44,8 @@
             <FilterForm :value="locationQuery"
                         :devices="devices"
                         :disabled="loading"
-                        :has-next-page="hasNextPage"
-                        :has-prev-page="hasPrevPage"
                         :resolution="resolutionMeters"
                         @refresh="locationQuery = $event"
-                        @reset-page="locationQuery.minId = locationQuery.maxId = null"
-                        @next-page="fetchNextPage"
-                        @prev-page="fetchPrevPage"
                         @set-resolution="setResolution" />
           </div>
           <FilterButton @input="showControls = !showControls"
@@ -70,8 +65,12 @@
 
       <div class="timeline">
         <Timeline :loading="loading"
+                  :locationQuery="locationQuery"
                   :points="gpsPoints"
                   :show-metrics="showMetrics"
+                  @next-page="fetchNextPage"
+                  @prev-page="fetchPrevPage"
+                  @reset-page="resetPage"
                   @point-hover="onTimelinePointHover"
                   @show-metrics="setShowMetrics" />
       </div>
@@ -283,6 +282,12 @@ export default {
       this.locationQuery = prevPageQuery
     },
 
+    async resetPage() {
+      const oldQuery = { ...this.locationQuery }
+      this.locationQuery.minId = this.locationQuery.maxId = null
+      await this.processQueryChange(this.locationQuery, oldQuery)
+    },
+
     createMap(): Map {
       this.pointsLayer = this.createPointsLayer(Object.values(this.mappedPoints) as Point[])
       this.routesLayer = this.createRoutesLayer(Object.values(this.mappedPoints) as Point[])
@@ -431,6 +436,8 @@ export default {
         ...this.locationQuery,
         startDate: null,
         endDate: null,
+        minId: null,
+        maxId: null,
         minLongitude: startLon,
         minLatitude: startLat,
         maxLongitude: endLon,
@@ -444,6 +451,8 @@ export default {
       } else {
         this.locationQuery = {
           ...this.locationQuery,
+          minId: null,
+          maxId: null,
           minLongitude: null,
           minLatitude: null,
           maxLongitude: null,
@@ -451,18 +460,8 @@ export default {
         }
       }
     },
-  },
-
-  watch: {
-    locationQuery: {
-      async handler(newQuery: LocationQuery, oldQuery: LocationQuery) {
-        if (!this.isQueryChanged({
-          newValue: newQuery,
-          oldValue: oldQuery,
-        })) {
-          return
-        }
 
+    async processQueryChange(newQuery: LocationQuery, oldQuery: LocationQuery) {
         // If startDate/endDate have changed, reset minId/maxId
         if (newQuery.startDate !== oldQuery.startDate || newQuery.endDate !== oldQuery.endDate) {
           newQuery.minId = null
@@ -507,6 +506,20 @@ export default {
           this.refreshMap()
         }
       },
+  },
+
+  watch: {
+    locationQuery: {
+      async handler(newQuery: LocationQuery, oldQuery: LocationQuery) {
+        if (!this.isQueryChanged({
+          newValue: newQuery,
+          oldValue: oldQuery,
+        })) {
+          return
+        }
+
+        await this.processQueryChange(newQuery, oldQuery)
+      },
       deep: true,
     },
 
diff --git a/frontend/src/components/Timeline.vue b/frontend/src/components/Timeline.vue
index cf568d3..7cbb9fe 100644
--- a/frontend/src/components/Timeline.vue
+++ b/frontend/src/components/Timeline.vue
@@ -23,9 +23,31 @@
         </button>
       </div>
 
+      <div class="page-button-container">
+        <button @click="$emit('prev-page')"
+                title="Previous results">
+          <font-awesome-icon icon="chevron-left" />
+        </button>
+      </div>
+
       <div class="timeline">
         <Line :data="graphData" :options="graphOptions" />
       </div>
+
+      <div class="page-button-container">
+        <button @click="$emit('next-page')"
+                title="Next results">
+          <font-awesome-icon icon="chevron-right" />
+        </button>
+      </div>
+
+      <div class="page-button-container"
+           v-if="locationQuery?.minId || locationQuery?.maxId">
+        <button @click="$emit('reset-page')"
+                title="Reset pagination">
+          <font-awesome-icon icon="fas fa-undo" />
+        </button>
+      </div>
     </div>
   </div>
 </template>
@@ -47,6 +69,7 @@ import 'chartjs-adapter-date-fns';
 
 import Geo from '../mixins/Geo.vue';
 import GPSPoint from '../models/GPSPoint';
+import LocationQuery from '../models/LocationQuery';
 import TimelineMetricsConfiguration from '../models/TimelineMetricsConfiguration';
 
 ChartJS.register(
@@ -60,7 +83,13 @@ ChartJS.register(
 );
 
 export default {
-  emits: ['point-hover', 'show-metrics'],
+  emits: [
+    'next-page',
+    'point-hover',
+    'prev-page',
+    'reset-page',
+    'show-metrics',
+  ],
   mixins: [Geo],
   components: {
     Line,
@@ -71,6 +100,9 @@ export default {
       type: Boolean,
       default: false,
     },
+    locationQuery: {
+      type: LocationQuery,
+    },
     points: {
       type: Array as () => GPSPoint[],
       default: () => [],
@@ -332,4 +364,26 @@ $options-width: 5em;
     }
   }
 }
+
+.page-button-container {
+  width: 3em;
+  height: 100%;
+  display: flex;
+  justify-content: center;
+  align-items: center;
+
+  button {
+    width: 100%;
+    height: 100%;
+    font-size: 1em;
+    background-color: var(--color-background);
+    border: 0;
+    margin-left: 0.5em;
+    cursor: pointer;
+
+    &:hover {
+      color: var(--color-hover);
+    }
+  }
+}
 </style>
diff --git a/frontend/src/components/filter/Form.vue b/frontend/src/components/filter/Form.vue
index 671805c..61ddcba 100644
--- a/frontend/src/components/filter/Form.vue
+++ b/frontend/src/components/filter/Form.vue
@@ -86,24 +86,6 @@
     </div>
 
     <div class="pagination-container">
-      <div class="page-button-container">
-        <button type="button"
-                :disabled="disabled"
-                v-if="value?.minId || value?.maxId"
-                @click.stop="$emit('reset-page')">
-          <font-awesome-icon icon="fas fa-undo" />
-        </button>
-      </div>
-
-      <div class="page-button-container">
-        <button type="button"
-                @click="$emit('prev-page')"
-                title="Previous Results"
-                :disabled="disabled || !hasPrevPage">
-          <font-awesome-icon icon="fas fa-chevron-left" />
-        </button>
-      </div>
-
       <div class="limit-container">
         <label for="limit">Max Results</label>
         <input type="number"
@@ -115,15 +97,6 @@
                :disabled="disabled"
                min="1" />
       </div>
-
-      <div class="page-button-container">
-        <button type="button"
-                @click="$emit('next-page')"
-                title="Next Results"
-                :disabled="disabled || !hasNextPage">
-          <font-awesome-icon icon="fas fa-chevron-right" />
-        </button>
-      </div>
     </div>
 
     <div class="resolution-container">
@@ -176,9 +149,6 @@ import UserDevice from '../../models/UserDevice'
 export default {
   mixins: [LocationQueryMixin],
   emit: [
-    'next-page',
-    'prev-page',
-    'reset-page',
     'refresh',
     'set-resolution',
   ],
@@ -193,14 +163,6 @@ export default {
       type: Boolean,
       default: false,
     },
-    hasPrevPage: {
-      type: Boolean,
-      default: true,
-    },
-    hasNextPage: {
-      type: Boolean,
-      default: true,
-    },
     resolution: {
       type: Number,
       required: true,
@@ -432,11 +394,6 @@ export default {
       align-items: center;
     }
 
-    .page-button-container {
-      display: flex;
-      justify-content: center;
-    }
-
     label {
       margin-bottom: 0.25em;
     }