Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 添加 info 页面来展示 Package 和测例信息 #97

Merged
merged 10 commits into from
Oct 29, 2024
33 changes: 33 additions & 0 deletions os-checks/components/InfoTestCases.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
<template>

<DataTable :value="data" showGridlines>

<Column field="idx" header="Idx" />
<Column field="binary_name" header="Binary Name" />
<Column field="kind" header="Kind" />
<Column field="test" header="Test Case" />

</DataTable>

</template>

<script setup lang="ts">
import type { Test } from '~/shared/info';

const { tests } = defineProps<{ tests: Test[] }>();

const data = computed(() => {
let idx = 0;
return tests.map(test => {
return test.testcases.map(t => {
idx += 1;
return {
idx,
binary_name: test.binary_name,
kind: test.kind,
test: t,
}
})
}).flat();
});
</script>
4 changes: 4 additions & 0 deletions os-checks/components/TopBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@
<Button title="Github Workflows" icon="pi pi-bell" />
</NuxtLink>

<NuxtLink to="/info">
<Button title="Package & Testcase Infomation" icon="pi pi-microchip" />
</NuxtLink>

</div>

<div class="topBarRight">
Expand Down
4 changes: 2 additions & 2 deletions os-checks/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -147,13 +147,13 @@ const progressRatio = computed(() => {
}

.nav-link {
color: #336ad7;
color: var(--p-indigo-500);
/* 统一的链接颜色 */
text-decoration: none;
}

.nav-link.router-link-active {
color: #336ad7;
color: var(--p-indigo-500);
/* 重置激活链接的颜色 */
}

Expand Down
252 changes: 252 additions & 0 deletions os-checks/pages/info.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
<template>
<div>
<DataTable :value="data" tableStyle="min-width: 50rem;" scrollable scrollHeight="800px" showGridlines
selectionMode="single" v-model:selection="selectedPkg" v-model:filters="filters"
:globalFilterFields="['user', 'repo', 'pkg', 'description', 'categories', 'os_categories']" removableSort
sortMode="multiple" paginator :rows="10" :rowsPerPageOptions="[5, 10, 20, 50, 100, 200, 1000]">

<template #header>
<div style="display: flex; justify-content: space-between;">
<div style="display: flex; gap: 20px;">
<MultiSelect v-model="selectedCategories" display="chip" :options="categories" filter :maxSelectedLabels="4"
placeholder="Select Categories" />

<MultiSelect v-model="selectedOSCategories" display="chip" :options="os_categories" filter
:maxSelectedLabels="4" placeholder="Select OS Categories" />

<MultiSelect v-model="selectedAuthors" display="chip" :options="authors" filter :maxSelectedLabels="4"
placeholder="Select Authors" />
</div>

<div style="width: 30%">
<IconField>
<InputIcon>
<i class="pi pi-search" />
</InputIcon>
<InputText style="width: 100%" v-model="filters['global'].value"
placeholder="Search in all text columns" />
</IconField>
</div>

</div>
</template>

<Column frozen sortable field="idx" header="Idx" />
<Column frozen sortable field="user" header="User" style="min-width: 150px;" />
<Column frozen sortable field="repo" header="Repo" style="min-width: 180px;" />
<Column frozen sortable field="pkg" header="Package" style="min-width: 200px;" />

<Column sortable field="version" header="Version" style="text-align: center;" />
<Column sortable field="dependencies" header="Depen-dencies" style="text-align: center;" />

<Column sortable field="testcases" header="Test Cases" style="text-align: center;" />

<Column sortable field="tests" header="Tests" style="text-align: center;" />
<Column sortable field="examples" header="Examples" style="text-align: center;" />
<Column sortable field="benches" header="Benches" style="text-align: center;" />

<Column sortable field="categories" header="Categories" style="min-width: 210px;">
<template #body="{ data: { categories } }">
<div v-for="tag of categories">
<Tag severity="warn" :value="tag" style="margin-bottom: 5px;"></Tag>
</div>
</template>
</Column>

<Column sortable field="os_categories" header="OS Categories">
<template #body="{ data: { os_categories } }">
<div v-for="tag of os_categories">
<Tag severity="warn" :value="tag" style="margin-bottom: 5px;"></Tag>
</div>
</template>
</Column>

<Column field="description" header="Description" style="min-width: 400px;" />

<Column sortable field="author" header="Author" style="min-width: 400px;">
<template #body="{ data: { author } }">
<div v-for="tag of author">
<Tag severity="info" :value="tag" style="margin-bottom: 5px;"></Tag>
</div>
</template>
</Column>

</DataTable>

<Dialog v-model:visible="dialogShow" modal :style="{ width: '70%' }">
<template #header>
<span style="display: inline-flex; justify-content: center; gap: 40px; font-size: larger; font-weight: bold;">
<div>
<NuxtLink :to="dialogHeader?.repo_url" target="_blank">
<Tag icon="pi pi-github" severity="info" style="font-weight: bold;">
{{ dialogHeader?.repo }}
</Tag>
</NuxtLink>
</div>

<div>Test Cases of package
<span style="color: var(--p-emerald-500); margin-right: 5px;">{{ dialogHeader?.pkg_name }}</span>
</div>
</span>
</template>

<div>
<div class="dialog-header">
Description: <b style="color: var(--p-emerald-500)">{{ dialogHeader?.pkg.description }}</b>
</div>
<div class="dialog-header">
Categories:
<Tag v-for="tag of dialogHeader?.pkg.categories" severity="warn" :value="tag" style="margin-right: 6px;" />
</div>
<div class="dialog-header">
OS Categories:
<Tag v-for="tag of dialogHeader?.pkg.os_categories" severity="warn" :value="tag" style="margin-right: 6px;" />
</div>
<div class="dialog-header">
Authors:
<Tag v-for="tag of dialogHeader?.pkg.author" severity="info" :value="tag" style="margin-bottom: 5px;"></Tag>
</div>

<InfoTestCases :tests="testCases" />
</div>
</Dialog>
</div>
</template>

<script setup lang="ts">
import type { Pkg, PkgInfo, Test } from '~/shared/info';
import { FilterMatchMode } from '@primevue/core/api';

// interactive filter/search inputs
const filters = ref<any>({
global: { value: null, matchMode: FilterMatchMode.CONTAINS },
});

const summaries = ref<PkgInfo[]>([]);

githubFetch<PkgInfo[]>({
path: "plugin/cargo/info/summaries.json"
}).then(val => {
summaries.value = val;
});

const summaryTable = computed<SummaryTable[]>(() => {
const value = summaries.value.map(val => {
return Object.entries(val.pkgs).map(([name, pkg]) => {
return {
idx: 0,
user: val.user,
repo: val.repo,
pkg: name,
version: pkg.version,
dependencies: pkg.dependencies || null,
testcases: pkg.testcases ? pkg.testcases.pkg_tests_count : null,
tests: pkg.tests || null,
examples: pkg.examples || null,
benches: pkg.benches || null,
author: pkg.author.length === 0 ? null : pkg.author,
description: pkg.description,
categories: pkg.categories.length === 0 ? null : pkg.categories,
os_categories: pkg.os_categories.length === 0 ? null : pkg.os_categories,
}
})
}).flat();

return value.sort((a, b) => {
const a_test = a.testcases ?? 0;
const b_test = b.testcases ?? 0;
if (a_test < b_test) {
return 1;
} else if (a_test > b_test) {
return -1;
} else if (a.user < b.user) {
return -1;
} else if (a.user > b.user) {
return 1;
} else if (a.repo < b.repo) {
return -1;
} else if (a.repo > b.repo) {
return 1;
} else if (a.pkg < b.pkg) {
return -1;
} else if (a.pkg > b.pkg) {
return 1;
}
return 0;
}).map((val, idx) => {
val.idx = idx + 1;
return val;
});
});

type SummaryTable = { idx: number; user: string; repo: string; pkg: string; version: string; dependencies: number | null; testcases: number | null; tests: number | null; examples: number | null; benches: number | null; author: string[] | null; description: string[]; categories: string[] | null; os_categories: string[] | null; };
const data = ref<SummaryTable[]>([]);
watch(summaryTable, (val) => data.value = val);

const categories = computed(() => [...new Set(summaryTable.value.map(val => val.categories).flat().filter(c => c))].sort());
const os_categories = computed(() => [...new Set(summaryTable.value.map(val => val.os_categories).flat().filter(c => c))].sort());
const authors = computed(() => [...new Set(summaryTable.value.map(val => val.author).flat().filter(c => c))].sort());
const selectedCategories = ref<string[]>([]);
const selectedOSCategories = ref<string[]>([]);
const selectedAuthors = ref<string[]>([]);
watchEffect(() => {
const cat = selectedCategories.value;
const os_cat = selectedOSCategories.value;
const au = selectedAuthors.value;

const is_empty_cat = cat.length === 0;
const is_empty_os_cat = os_cat.length === 0;
const is_empty_au = au.length === 0;

// reset
if (is_empty_cat && is_empty_os_cat && is_empty_au) {
data.value = summaryTable.value;
return;
}

data.value = summaryTable.value.filter(val => {
const find_cat = cat.find(c => val.categories?.find(vc => vc === c));
const find_os_cat = os_cat.find(o => val.os_categories?.find(vo => vo === o));
const find_au = au.find(a => val.author?.find(va => va === a));

return (is_empty_cat ? true : find_cat) && (is_empty_os_cat ? true : find_os_cat) && (is_empty_au ? true : find_au)
}).map((x, idx) => {
x.idx = idx + 1;
return x;
});
});

const dialogShow = ref(false);
const dialogHeader = ref<{ repo: string, repo_url: string, pkg_name: string, pkg: Pkg } | null>();
const testCases = ref<Test[]>([]);

type SelectedRow = { user: string, repo: string, pkg: string, testcases: number };
const selectedPkg = ref<SelectedRow | null>(null);
watch(selectedPkg, val => {

if (!val?.testcases) { return; }

// for now, pop up a dialog to display testcases only if any
dialogShow.value = true;

const pkg = summaries.value
.find(summary => summary.user === val.user && summary.repo === val.repo)
?.pkgs[val.pkg];

if (!pkg?.testcases) { return; }

const repo = `${val.user}/${val.repo}`;
const repo_url = `https://github.com/${repo}`;
dialogHeader.value = { repo, repo_url, pkg_name: val.pkg, pkg };

testCases.value = pkg.testcases.tests;
});


</script>

<style lang="css">
.dialog-header {
margin-bottom: 10px;
}
</style>
34 changes: 34 additions & 0 deletions os-checks/shared/info.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
export type PkgInfo = {
user: string,
repo: string,
pkgs: { [key: string]: Pkg }
}

export type Pkg = {
version: string,
dependencies: number,
lib: boolean,
bin: boolean,
testcases: TestCases | null,
tests: number,
examples: number,
benches: number,
author: string[]
description: string[],
categories: string[]
os_categories: string[],
}

export type TestCases = {
tests: Test[],
pkg_tests_count: number,
workspace_tests_count: number,
}

export type Test = {
id: string,
kind: string,
binary_name: string,
binary_path: string,
testcases: string[]
}
Loading