implement admin health page

This commit is contained in:
MiniDigger 2022-03-19 17:32:10 +01:00 committed by MiniDigger | Martin
parent a600cb0888
commit 3da7fe1422
3 changed files with 109 additions and 5 deletions

View File

@ -218,9 +218,9 @@ once QA has passed, the checkboxes can be removed and the page can be ~~striked
- [ ] design
- [ ] qa
- health
- [ ] fetch
- [ ] layout
- [ ] functionality
- [x] fetch
- [x] layout
- [x] functionality
- [ ] design
- [ ] qa
- log

View File

@ -1,7 +1,7 @@
import { useApi, useInternalApi } from "~/composables/useApi";
import { PaginatedResult, Project, User } from "hangar-api";
import { useInitialState } from "~/composables/useInitialState";
import { Flag, HangarNotification, Invites } from "hangar-internal";
import { Flag, HangarNotification, HealthReport, Invites } from "hangar-internal";
export async function useProjects(pagination = { limit: 25, offset: 0 }, blocking = true) {
return await useInitialState("useProjects", () => useApi<PaginatedResult<Project>>("projects", false, "get", pagination), blocking);
@ -34,3 +34,7 @@ export async function useNotifications(blocking = true) {
export async function useFlags(blocking = true) {
return await useInitialState("useFlags", () => useInternalApi<Flag[]>("flags/", false), blocking);
}
export async function useHealthReport(blocking = true) {
return await useInitialState("useHealthReport", () => useInternalApi<HealthReport>("admin/health", false), blocking);
}

View File

@ -1,5 +1,105 @@
<script lang="ts" setup>
import { useContext } from "vite-ssr/vue";
import { useI18n } from "vue-i18n";
import { useRoute } from "vue-router";
import { useHealthReport } from "~/composables/useApiHelper";
import { handleRequestError } from "~/composables/useErrorHandling";
import { prettyDateTime } from "~/composables/useDate";
const ctx = useContext();
const i18n = useI18n();
const { params } = useRoute();
const healthReport = await useHealthReport().catch((e) => handleRequestError(e, ctx, i18n));
</script>
<template>
<h1>health</h1>
<h1>{{ i18n.t("health.title") }}</h1>
<div class="flex flex-wrap">
<div class="basis-12/12 md:basis-6/12 p-4">
<div class="bg-gray-200 rounded h-full p-2">
<h2>{{ i18n.t("health.noTopicProject") }}</h2>
<ul>
<li v-for="project in healthReport.noTopicProjects" :key="project.namespace.slug + project.namespace.owner">
<router-link :to="'/' + project.namespace.owner + '/' + project.namespace.slug">
<strong>{{ project.namespace.owner + "/" + project.namespace.slug }}</strong>
</router-link>
</li>
<li v-if="!healthReport.noTopicProjects || healthReport.noTopicProjects.length === 0">
{{ i18n.t("health.empty") }}
</li>
</ul>
</div>
</div>
<div class="basis-12/12 md:basis-6/12 p-4">
<div class="bg-gray-200 rounded h-full p-2">
<h2>{{ i18n.t("health.erroredJobs") }}</h2>
<ul>
<li v-for="job in healthReport.erroredJobs" :key="job.jobType + new Date(job.lastUpdated).toISOString()">
{{ i18n.t("health.jobText", [job.jobType, job.lastErrorDescriptor, prettyDateTime(job.lastUpdated)]) }}
</li>
<li v-if="!healthReport.erroredJobs || healthReport.erroredJobs.length === 0">
{{ i18n.t("health.empty") }}
</li>
</ul>
</div>
</div>
<div class="basis-12/12 md:basis-6/12 p-4">
<div class="bg-gray-200 rounded h-full p-2">
<h2>{{ i18n.t("health.staleProjects") }}</h2>
<ul>
<li v-for="project in healthReport.staleProjects" :key="project.namespace.slug + project.namespace.owner">
<router-link :to="'/' + project.namespace.owner + '/' + project.namespace.slug">
<strong>{{ project.namespace.owner + "/" + project.namespace.slug }}</strong>
</router-link>
</li>
<li v-if="!healthReport.staleProjects || healthReport.staleProjects.length === 0">
{{ i18n.t("health.empty") }}
</li>
</ul>
</div>
</div>
<div class="basis-12/12 md:basis-6/12 p-4">
<div class="bg-gray-200 rounded h-full p-2">
<h2>{{ i18n.t("health.notPublicProjects") }}</h2>
<ul>
<li v-for="project in healthReport.nonPublicProjects" :key="project.namespace.slug + project.namespace.owner">
<router-link :to="'/' + project.namespace.owner + '/' + project.namespace.slug">
<strong>{{ project.namespace.owner + "/" + project.namespace.slug }}</strong>
<small>{{ i18n.t("visibility.name." + project.visibility) }}</small>
</router-link>
</li>
<li v-if="!healthReport.nonPublicProjects || healthReport.nonPublicProjects.length === 0">
{{ i18n.t("health.empty") }}
</li>
</ul>
</div>
</div>
<div class="basis-12/12 md:basis-6/12 p-4">
<div class="bg-gray-200 rounded h-full p-2">
<h2>{{ i18n.t("health.noPlatform") }}</h2>
<ul>
<li>TODO: Implementation</li>
<!--TODO idek what this is for?-->
<!--<li v-if="!healthReport.noPlatform || healthReport.noPlatform.length === 0">{{ i18n.t('health.empty') }}</li>-->
</ul>
</div>
</div>
<div class="basis-12/12 md:basis-6/12 p-4">
<div class="bg-gray-200 rounded h-full p-2">
<h2>{{ i18n.t("health.missingFileProjects") }}</h2>
<ul>
<li v-for="project in healthReport.missingFiles" :key="project.namespace.slug + project.namespace.owner">
<router-link :to="'/' + project.namespace.owner + '/' + project.namespace.slug">
<strong>{{ project.namespace.owner + "/" + project.namespace.slug }}</strong>
</router-link>
</li>
<li v-if="!healthReport.missingFiles || healthReport.missingFiles.length === 0">
{{ i18n.t("health.empty") }}
</li>
</ul>
</div>
</div>
</div>
</template>
<route lang="yaml">