main
vue 102 lines 3.71 KB
Raw
1 <template>
2 <div class="flex items-center gap-6">
3 <n-progress
4 v-if="showScore"
5 type="circle"
6 :percentage="config.last_audit_score ?? 0"
7 :status="scoreStatus"
8 gap-position="bottom"
9 >
10 <div class="flex flex-col items-center justify-between gap-1 text-center">
11 <span class="text-xs">Security Score</span>
12 </div>
13 </n-progress>
14
15 <div v-if="showGrade || hasMetaFields" class="flex min-w-0 flex-1 flex-col gap-3">
16 <div v-if="showGrade" class="flex items-end justify-between gap-3">
17 <div class="min-w-0">
18 <p class="text-secondary mb-1 text-[10px] font-medium tracking-widest uppercase">Grade</p>
19 <GitHubAuditGradeLabel :grade="config.last_audit_grade" class="text-4xl" />
20 </div>
21 <p
22 v-if="showScore && config.last_audit_score != null"
23 class="text-secondary shrink-0 font-mono text-xs tabular-nums"
24 >
25 {{ config.last_audit_score.toFixed(1) }}%
26 </p>
27 </div>
28
29 <dl v-if="hasMetaFields" class="border-border flex flex-col gap-2" :class="{ 'border-t pt-3': showGrade }">
30 <div v-if="showCustomer" class="flex items-baseline justify-between gap-3">
31 <dt class="text-secondary shrink-0 text-[10px] tracking-wider uppercase">Customer</dt>
32 <dd class="text-default min-w-0 truncate font-mono text-xs">
33 {{ config.customer_code }}
34 </dd>
35 </div>
36 <div v-if="showOrganization" class="flex items-baseline justify-between gap-3">
37 <dt class="text-secondary shrink-0 text-[10px] tracking-wider uppercase">Organization</dt>
38 <dd class="text-default min-w-0 truncate font-mono text-xs">
39 {{ config.organization }}
40 </dd>
41 </div>
42 <div v-if="showLastAudit" class="flex items-baseline justify-between gap-3">
43 <dt class="text-secondary shrink-0 text-[10px] tracking-wider uppercase">Last audit</dt>
44 <dd class="text-default min-w-0 truncate text-right font-mono text-xs tabular-nums">
45 {{ config.last_audit_at ? formatDate(config.last_audit_at, dFormats.datetime) : "" }}
46 </dd>
47 </div>
48 <div v-if="showTokenType" class="flex items-baseline justify-between gap-3">
49 <dt class="text-secondary shrink-0 text-[10px] tracking-wider uppercase">Token type</dt>
50 <dd class="text-default min-w-0 truncate text-right font-mono text-xs">
51 {{ tokenTypeLabel }}
52 </dd>
53 </div>
54 </dl>
55 </div>
56 </div>
57 </template>
58
59 <script setup lang="ts">
60 import type { GitHubAuditConfig } from "@/types/githubAudit.d"
61 import { NProgress } from "naive-ui"
62 import { computed } from "vue"
63 import { useSettingsStore } from "@/stores/settings"
64 import { formatDate } from "@/utils/format"
65 import GitHubAuditGradeLabel from "./GitHubAuditGradeLabel.vue"
66
67 export type GitHubAuditConfigSummaryMetaFields = "all" | "card" | "none"
68
69 const props = withDefaults(
70 defineProps<{
71 config: GitHubAuditConfig
72 showScore?: boolean
73 showGrade?: boolean
74 metaFields?: GitHubAuditConfigSummaryMetaFields
75 }>(),
76 {
77 showScore: true,
78 showGrade: true,
79 metaFields: "all"
80 }
81 )
82
83 const dFormats = useSettingsStore().dateFormat
84
85 const showCustomer = computed(() => props.metaFields === "all" || props.metaFields === "card")
86 const showOrganization = computed(() => props.metaFields === "all")
87 const showLastAudit = computed(() => props.metaFields === "all" || props.metaFields === "card")
88 const showTokenType = computed(() => props.metaFields === "all")
89
90 const hasMetaFields = computed(
91 () => showCustomer.value || showOrganization.value || showLastAudit.value || showTokenType.value
92 )
93
94 const scoreStatus = computed(() => {
95 const score = props.config.last_audit_score ?? 0
96 if (score >= 80) return "success"
97 if (score >= 60) return "warning"
98 return "error"
99 })
100
101 const tokenTypeLabel = computed(() => (props.config.token_type === "pat" ? "Personal Access Token" : "GitHub App"))
102 </script>