]> git.ipfire.org Git - pbs.git/commitdiff
frontend: Create a store and listing component for mirrors
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 4 Jul 2025 13:53:37 +0000 (13:53 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 4 Jul 2025 13:53:37 +0000 (13:53 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
frontend/src/api/mirrors.ts
frontend/src/components/MirrorList.vue [new file with mode: 0644]
frontend/src/stores/mirrors.ts [new file with mode: 0644]
frontend/src/types/Mirror.ts [deleted file]
frontend/src/views/MirrorsView.vue

index a082f3351ed3551444dfca57c6024a1f9685ebb0..b0c5301bd4a61626a7fb714e97427a7aa01c5840 100644 (file)
@@ -1,5 +1,45 @@
 import api from "@/api"
-import type { Mirror } from "@/types/Mirror";
+
+export interface Mirror {
+       // Hostanme
+       hostname: string;
+
+       // Path
+       path: string;
+
+       // Owner
+       owner: string;
+
+       // Contact
+       contact: string;
+
+       // Notes
+       notes: string;
+
+       // Country Code
+       country_code: string;
+
+       // ASN
+       asn: number;
+
+       // AS Name
+       as_name: string | null;
+
+       // Supports IPv6?
+       supports_ipv6: boolean;
+
+       // Supports IPv4?
+       supports_ipv4: boolean;
+
+       // Last Check Was Successful?
+       last_check_success: boolean;
+
+       // Last Check At
+       last_check_at: Date;
+
+       // Last Sync At
+       last_sync_at: Date;
+}
 
 // Fetch all mirrors
 export async function fetchMirrors(): Promise<Mirror[]> {
diff --git a/frontend/src/components/MirrorList.vue b/frontend/src/components/MirrorList.vue
new file mode 100644 (file)
index 0000000..a907bd2
--- /dev/null
@@ -0,0 +1,51 @@
+<script setup lang="ts">
+       import { onMounted } from 'vue'
+       import { useMirrorStore } from '@/stores/mirrors'
+       import { getCountryName } from "@/utils/i18n"
+
+       // Components
+       import Box from "@/components/Box.vue"
+       import Loader from "@/components/Loader.vue"
+       import Notification from "@/components/Notification.vue"
+       import Tags from "@/components/Tags.vue"
+       import Tag from "@/components/Tag.vue"
+
+       // Load the store
+       const mirrorStore = useMirrorStore()
+
+       // Load all mirrors
+       onMounted(() => {
+               mirrorStore.loadMirrors()
+       })
+</script>
+
+<template>
+       <Loader v-if="mirrorStore.loading" />
+
+       <Notification v-else-if="mirrorStore.error" is-danger>
+               {{ mirrorStore.error }}
+       </Notification>
+
+       <Box v-else v-for="mirror in mirrorStore.mirrors" :key="mirror.hostname"
+                       :title="mirror.hostname" :subtitle="mirror.owner">
+               <div class="level">
+                       <!-- Show the country -->
+                       <div class="level-item">
+                               {{ getCountryName(mirror.country_code) }}
+                       </div>
+
+                       <!-- Show tags of which protocols are supported -->
+                       <div class="level-item">
+                               <Tags>
+                                       <Tag v-if="mirror.supports_ipv6" :title="$t('Supports IPv6')" is-success>
+                                               {{ $t('IPv6') }}
+                                       </Tag>
+
+                                       <Tag v-if="mirror.supports_ipv4" :title="$t('Supports IPv4')" is-success>
+                                               {{ $t('IPv4') }}
+                                       </Tag>
+                               </Tags>
+                       </div>
+               </div>
+       </Box>
+</template>
diff --git a/frontend/src/stores/mirrors.ts b/frontend/src/stores/mirrors.ts
new file mode 100644 (file)
index 0000000..f76ef9b
--- /dev/null
@@ -0,0 +1,27 @@
+import { defineStore } from "pinia"
+
+// Fetch the mirror API
+import type { Mirror } from "@/api/mirrors"
+import { fetchMirrors } from "@/api/mirrors"
+
+export const useMirrorStore = defineStore("mirrors", {
+       state: () => ({
+               mirrors: [] as Mirror[],
+               loading: false,
+               error: null as string | null,
+       }),
+
+       actions: {
+               async loadMirrors() {
+                       this.loading = true
+                       this.error = null
+                       try {
+                               this.mirrors = await fetchMirrors()
+                       } catch (err) {
+                               this.error = "Failed to load mirrors"
+                       } finally {
+                               this.loading = false
+                       }
+               },
+       },
+})
diff --git a/frontend/src/types/Mirror.ts b/frontend/src/types/Mirror.ts
deleted file mode 100644 (file)
index 7bbb690..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
-       Defines a Mirror
-*/
-export interface Mirror {
-       // Hostanme
-       hostname: string;
-
-       // Path
-       path: string;
-
-       // Owner
-       owner: string;
-
-       // Contact
-       contact: string;
-
-       // Notes
-       notes: string;
-
-       // Country Code
-       country_code: string;
-
-       // ASN
-       asn: number;
-
-       // AS Name
-       as_name: string | null;
-
-       // Supports IPv6?
-       supports_ipv6: boolean;
-
-       // Supports IPv4?
-       supports_ipv4: boolean;
-
-       // Last Check Was Successful?
-       last_check_success: boolean;
-
-       // Last Check At
-       last_check_at: Date;
-
-       // Last Sync At
-       last_sync_at: Date;
-}
index 1323ccfb0099e99ea9fe48ec858c32768293c31a..bae033a3bea7bac461c579b8232caa02514c272a 100644 (file)
@@ -1,51 +1,11 @@
 <script setup lang="ts">
-       import { ref, onMounted } from "vue"
-       import type { Mirror } from "@/types/Mirror"
-       import { fetchMirrors } from "@/api/mirrors"
-       import { getCountryName } from "@/utils/i18n"
-
-       // Import UI components
-       import Box from "@/components/Box.vue"
+       // Components
+       import MirrorList from "@/components/MirrorList.vue"
        import Section from "@/components/Section.vue"
-       import Tags from "@/components/Tags.vue"
-       import Tag from "@/components/Tag.vue"
-
-       // Mirrors
-       const mirrors = ref<Mirror[]>([]);
-
-       // Fetch all builders as soon as we are mounted
-       onMounted(async () => {
-               try {
-                       mirrors.value = await fetchMirrors();
-               } catch (err) {
-                       console.error(err);
-               }
-       });
 </script>
 
 <template>
        <Section :title="$t('Mirrors')">
-               <Box v-for="mirror in mirrors" :key="mirror.hostname"
-                               :title="mirror.hostname" :subtitle="mirror.owner">
-                       <div class="level">
-                               <!-- Show the country -->
-                               <div class="level-item">
-                                       {{ getCountryName(mirror.country_code) }}
-                               </div>
-
-                               <!-- Show tags of which protocols are supported -->
-                               <div class="level-item">
-                                       <Tags>
-                                               <Tag v-if="mirror.supports_ipv6" :title="$t('Supports IPv6')" is-success>
-                                                       {{ $t('IPv6') }}
-                                               </Tag>
-
-                                               <Tag v-if="mirror.supports_ipv4" :title="$t('Supports IPv4')" is-success>
-                                                       {{ $t('IPv4') }}
-                                               </Tag>
-                                       </Tags>
-                               </div>
-                       </div>
-               </Box>
+               <MirrorList />
        </Section>
 </template>