--- /dev/null
+import api from "@/api"
+
+export interface Build {
+ // Name
+ name: string;
+
+ // EVR
+ evr: string;
+
+ // UUID
+ uuid: string;
+
+ // Created At
+ created_at: Date;
+}
+
+// Fetch a build by its UUID
+export async function fetchBuild(uuid: string): Promise<Build> {
+ const response = await api.get(`/v1/builds/${uuid}`);
+ return response.data as Build;
+}
--- /dev/null
+<script setup lang="ts">
+ // Import type
+ import type { Build } from "@/api/builds";
+
+ // Fetch the build
+ defineProps<{
+ build: Build
+ }>();
+</script>
+
+<template>
+ <div class="hero is-light">
+ <div class="hero-body">
+ <Container>
+ <!-- Name & Version Information -->
+ <h3 class="title is-3">{{ build.name }}-{{ build.evr }}</h3>
+ </Container>
+ </div>
+ </div>
+</template>
--- /dev/null
+import { ref } from "vue";
+
+// API
+import type { Build } from "@/api/builds";
+import {
+ fetchBuild,
+} from "@/api/builds";
+
+export function useBuild(uuid: string) {
+ const build = ref<Build>();
+
+ // Fetch the build
+ async function loadBuild() {
+ build.value = await fetchBuild(uuid);
+ }
+
+ return {
+ build,
+ loadBuild,
+ };
+}
import HomeView from '../views/HomeView.vue'
import LoginView from "../views/LoginView.vue"
+import BuildView from "../views/BuildView.vue"
import BuildersView from "../views/BuildersView.vue"
import MirrorsView from "../views/MirrorsView.vue"
import NotFoundView from "../views/NotFoundView.vue"
component: LoginView,
},
+ // Builds
+ {
+ path: "/builds/:uuid",
+ name: "BuildView",
+ component: BuildView,
+ props: true,
+ },
+
// Builders
{
path: "/builders",
--- /dev/null
+<script setup lang="ts">
+ import { onMounted } from "vue";
+ import { useRoute } from "vue-router";
+
+ // Composables
+ import { useBuild } from "@/composables/builds";
+
+ // Import UI components
+ import BuildHeader from "@/components/BuildHeader.vue";
+
+ // Fetch the build UUID from the URL
+ const { uuid } = defineProps<{
+ uuid: string,
+ }>()
+
+ // Fetch the build
+ const { build, loadBuild } = useBuild(uuid);
+
+ onMounted(async () => {
+ await loadBuild();
+ });
+</script>
+
+<template>
+ <!-- Show the header -->
+ <BuildHeader v-if="build" :build="build" />
+</template>
class Build(sqlmodel.SQLModel, database.BackendMixin, database.SoftDeleteMixin, table=True):
__tablename__ = "builds"
- def __str__(self):
- return "%s %s" % (self.pkg.name, self.pkg.evr)
+ def __repr__(self):
+ return "<%s %s (%s-%s)>" % (self.__class__.__name__, self.uuid, self.pkg.name, self.pkg.evr)
def __lt__(self, other):
if isinstance(other, self.__class__):
id: int = sqlmodel.Field(primary_key=True, exclude=True)
+ # Name
+
+ @pydantic.computed_field
+ @property
+ def name(self) -> str:
+ return self.pkg.name
+
+ # EVR
+
+ @pydantic.computed_field
+ @property
+ def evr(self) -> str:
+ return self.pkg.evr
+
+ # URL
+
@property
def url(self):
return "/builds/%s" % self.uuid
sa_relationship_kwargs={ "lazy" : "joined", "innerjoin" : True }
)
- @property
- def name(self):
- return "%s-%s" % (self.pkg.name, self.pkg.evr)
-
# Created At
created_at: datetime.datetime = sqlmodel.Field(