Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
4f23ba8
file-tree: user/repo/pkg/checker/target/features dropdowns
zjp-CN Feb 8, 2025
65e468a
file-tree: 隐藏无诊断的检查标签栏
zjp-CN Feb 8, 2025
811fb3f
FileTree2: 奇怪的 props 更新状态
zjp-CN Feb 9, 2025
9055ab0
file-tree: debug with Print
zjp-CN Feb 9, 2025
b05f094
file-tree: 反应式对象需要在模板内修改状态
zjp-CN Feb 9, 2025
c075ca0
chore: purge
zjp-CN Feb 9, 2025
011133d
file-tree: download raw report JSON considering the target
zjp-CN Feb 9, 2025
9a02cf6
fix(basic): kinds field changed; construct columns
zjp-CN Feb 9, 2025
cac22d3
file-tree: filter pkg (but with some bugs)
zjp-CN Feb 9, 2025
47c8024
fix(file-tree): selectedTarget is null if cleared
zjp-CN Feb 11, 2025
7afc3bb
file-tree: 下拉框显示诊断数量(暂时针对 pkg)
zjp-CN Feb 11, 2025
de9e1ef
file-tree: two-way binding (v-model) using defineModel
zjp-CN Feb 12, 2025
97b01bc
file-tree: replace Select with templates by DropDownWithCount
zjp-CN Feb 12, 2025
88b8bb9
file-tree: support Cheker and Kind filters
zjp-CN Feb 12, 2025
1e3c157
file-tree: 联动筛选:选择 checker 将更新 kind 和 pkg(初步)
zjp-CN Feb 13, 2025
bce938b
file-tree: play around with emit change event
zjp-CN Feb 13, 2025
2be4673
file-tree: 下拉框清除 checker 选项并联动 pkg
zjp-CN Feb 13, 2025
a0fd3b1
file-tree: support Kind filter
zjp-CN Feb 14, 2025
8a08858
file-tree: fix interaction between checker and kind filters
zjp-CN Feb 14, 2025
88e06d6
file-tree: define Dropdown class
zjp-CN Feb 14, 2025
25ec384
file-tree: restore the filter behavior
zjp-CN Feb 14, 2025
7cf97ff
file-tree: update filters as per got2
zjp-CN Feb 14, 2025
1b05bd5
file-tree: 修复 All* 计数和其他 option 不同步
zjp-CN Feb 14, 2025
500415a
file-tree: correct filters interaction (so far so good)
zjp-CN Feb 14, 2025
076dd33
file-tree: add count button
zjp-CN Feb 14, 2025
32f23b2
file-tree: 修复联合筛选导致的数据来源问题
zjp-CN Feb 15, 2025
e721fd2
file-tree: filters mutate target in place
zjp-CN Feb 15, 2025
666650c
file-tree: handle selectedKind that is not diagnosed
zjp-CN Feb 15, 2025
72f91c9
file-tree: apply checker filter if possible when switching to new data
zjp-CN Feb 15, 2025
4f2c018
file-tree: replace Target dropdown with DropDownWithCount widget
zjp-CN Feb 15, 2025
10b7153
file-tree: shortcuts for toggling filetree and filters panel
zjp-CN Feb 15, 2025
308efb5
file-tree: bind click event to display refs
zjp-CN Feb 15, 2025
1db20f3
file-tree: remove pkg property from FileTree2
zjp-CN Feb 15, 2025
183e02f
TargetDropDown: only displayed in /diagnostics page
zjp-CN Feb 15, 2025
1f0ae74
file-tree: adjust css style for Tabs and CodeBlock scrolling
zjp-CN Feb 15, 2025
a015d84
file-tree: move totol count to above filetree
zjp-CN Feb 15, 2025
e66eb58
file-tree: back to fullTabs via clicking total count btn or unselecti…
zjp-CN Feb 15, 2025
d53770a
file-tree: fix file-tree panel height & scrolling
zjp-CN Feb 15, 2025
ee522c5
type(Basic): remove features_sets
zjp-CN Feb 16, 2025
fb1eb3e
file-tree: make features empty due to removal of features_sets
zjp-CN Feb 16, 2025
b2d072e
file-tree: support basic features filter options
zjp-CN Feb 16, 2025
de0e89f
file-tree: keep "" features option; update_by_features
zjp-CN Feb 16, 2025
50b8ad1
file-tree: fix count in update_by_features
zjp-CN Feb 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions os-checks/components/DropDownWithCount.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<script lang="ts" setup>
import type { DropDownOptions } from '~/shared/file-tree/types';

type Props = { tag: string, counts: DropDownOptions, all: string };
const { tag, counts } = defineProps<Props>();
const selected = defineModel<string | null>({ default: null });
</script>

<template>

<span class="input">{{ tag }}:</span>
<span class="select">
<Select v-model="selected" filter showClear :options="counts.names">
<template #option="{ option }">
<Tag severity="danger" class="drop-down-options">{{ counts.counts[option] }}</Tag>
{{ option }}
</template>

<!-- <template #value="{ value }"> -->
<!-- {{ value || all }} -->
<!-- <Tag severity="danger" style="margin-left: 5px">{{ counts.counts[value || all] }}</Tag> -->
<!-- </template> -->
</Select>
</span>

</template>

<style scoped>
.input {
font-size: 14.5px;
font-weight: bold;
padding-right: 10px;
color: var(--p-button-primary-background);
}

.select {
padding-right: 10px;
}

.resolved-table {
--p-datatable-header-cell-color: var(--p-button-primary-background);
}

.sources {
color: var(--p-orange-400);
}

.sources-table {
--p-datatable-header-cell-color: var(--p-orange-400);
}

.drop-down-options {
margin-right: 8px;
width: 40px;
justify-content: right;
}
</style>
5 changes: 3 additions & 2 deletions os-checks/components/FileTree.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import type { FetchError } from 'ofetch';
import type { TreeNode } from 'primevue/treenode';
import type { FileTree, Kinds } from '~/shared/file-tree';
import { getEmpty } from '../shared/file-tree/utils';

type Props = { fetch_path: (target: string) => string };
const props = defineProps<Props>();
Expand All @@ -10,7 +11,7 @@ highlightRust();

const tabs = ref<CheckerResult[]>([]);
const selectedTab = ref("");
const fileTree = ref<FileTree>({ kinds_order: [], data: [] });
const fileTree = ref<FileTree>(getEmpty().fileTree);

const basic = useBasicStore();

Expand Down Expand Up @@ -46,7 +47,7 @@ basic.init_with_and_subscribe_to_current((target: string) => {
lang: "rust", severity: Severity.Info, disabled: false
}];
selectedTab.value = "All good! 🥳";
fileTree.value = { kinds_order: [], data: [] };
fileTree.value = getEmpty().fileTree;

// tabs.value = [{
// kind: "Not Exists!", raw: ["该目标架构下,无原始报告数据。"],
Expand Down
185 changes: 185 additions & 0 deletions os-checks/components/FileTree2.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
<script setup lang="ts">
import { cloneDeep } from 'es-toolkit/compat';
import type { TreeNode } from 'primevue/treenode';
import type { FileTree } from '~/shared/file-tree';
import { updateSelectedKey, type Get } from '~/shared/file-tree/utils';

type Props = { get: Get, count: number | null };
const { get, count } = defineProps<Props>();

const fullTabs = ref(cloneDeep(get.tabs));
watch(() => get, g => fullTabs.value = cloneDeep(g.tabs));

const filtered_fileTree = computed<FileTree>(() => get.fileTree);

const nodes = computed<TreeNode[]>(() => {
let nodes = [];

let key = 0;
for (const datum of filtered_fileTree.value.data) {
let node: TreeNode = {
key: (key++).toString(), label: `[${datum.count}] ${datum.repo} #${datum.pkg}`, children: [],
};
let count_fmt = 0;
let count_clippy_warn = 0;
let count_clippy_error = 0;
for (const report of datum.raw_reports) {
node.children?.push({
key: (key++).toString(),
label: `[${report.count}] ${report.file}`,
data: report.file
});

}
node.data = {
user: datum.user, repo: datum.repo, pkg: datum.pkg,
total: datum.count, fmt: count_fmt, clippy_warn: count_clippy_warn, clippy_error: count_clippy_error
};
nodes.push(node);
}
return nodes;
});

const selectedKey = ref({});
watch(() => ({ key: selectedKey.value, n: nodes.value, ft: filtered_fileTree.value }),
({ key, n, ft }) => {
const val = updateSelectedKey(key, n, ft);
if (val !== undefined) {
get.tabs = val.results;
get.selectedTab = val.selectedTab;
} else {
// display full diagnostics if none is selected or something is not found
get.tabs = cloneDeep(fullTabs.value);
}
});

function resetSelectKey() {
selectedKey.value = {};
get.tabs = cloneDeep(fullTabs.value);
}

// true means keeping file tree panel open (thus shows left arrow icon to indicate close)
const displayFileTree = ref(true);
const displayFileTreeIcon = computed<string>(() => displayFileTree.value ? "pi pi-angle-double-left" : "pi pi-angle-double-right");

// true means keeping filter panel open (thus shows up arrow icon to indicate close)
const displayFilters = defineModel<boolean>("filters", { default: true });
const displayFiltersIcon = computed<string>(() => displayFilters.value ? "pi pi-angle-double-up" : "pi pi-angle-double-down");

onMounted(() => {
document.addEventListener("keydown", ({ code }: KeyboardEvent) => {
if (code === "Space") displayFileTree.value = !displayFileTree.value;
else if (code === "Escape") displayFilters.value = !displayFilters.value;
else if (code === "ArrowLeft") displayFileTree.value = false;
else if (code === "ArrowRight") displayFileTree.value = true;
else if (code === "ArrowUp") displayFilters.value = false;
else if (code === "ArrowDown") displayFilters.value = true;
});
});

const { viewportHeight } = storeToRefs(useStyleStore());
const heightCodePanel = computed(() => {
const height = viewportHeight.value;
// add more space to scroll codeblock panel to the bottom if filters exist
const adjust = displayFilters.value ? 100 : 0;
return `${height * 0.85 - adjust}px`;
});
</script>

<template>
<div class="fileViewPanel">

<div class="fileViewNavi" v-if="displayFileTree">
<div style="height: 3.2rem; display: flex; justify-content: space-between; align-items: center;">
<div style="display: flex; justify-content: left; gap: 8px;">
<div style="margin-left: 10px;">
<Button class="btn" :icon="displayFileTreeIcon" severity="secondary" variant="text"
@click="() => displayFileTree = !displayFileTree" />
</div>
<div>
<Button class="btn" :icon="displayFiltersIcon" severity="secondary" variant="text"
@click="() => displayFilters = !displayFilters" />
</div>
</div>
<div v-if="count" style="padding-right: 0.6rem;">
<b style="margin-right: 10px;">Total Count:</b>
<Button class="btn" severity="danger" @click="resetSelectKey"> {{ count }} </Button>
</div>
</div>

<ScrollPanel class="fileViewMenu" :style="{ height: heightCodePanel }">
<PackageFileMenu :nodes="nodes" :selectedKey="selectedKey" @update:selectedKey="selectedKey = $event" />
</ScrollPanel>
</div>

<div class="fileViewResult">
<Tabs :value="get.selectedTab" scrollable>
<TabList>
<Tab v-for="tab in get.tabs" :value="tab.kind" :disabled="tab.disabled">
{{ tab.kind }}
<span class="tabBadge">
<Badge :value="tab.raw.length" :severity="tab.severity" />
</span>
</Tab>
</TabList>
<TabPanels>
<TabPanel v-for="tab in get.tabs" :value="tab.kind">
<ScrollPanel :dt="{ bar: { background: '{primary.color}' } }" :style="{ height: heightCodePanel }">
<CodeBlock :snippets="tab.raw" :lang="tab.lang" />
</ScrollPanel>
</TabPanel>
</TabPanels>
</Tabs>
</div>

</div>
</template>

<style scoped>
.tabBadge {
vertical-align: super;
--p-badge-padding: 0.2rem;
--p-badge-font-size: normal;
--p-badge-height: 1rem;
--p-badge-min-width: 1.5rem;
--p-badge-secondary-color: grey;
}

.fileViewPanel {
display: flex;
}

.fileViewNavi {
flex: 0 0 25%;
padding-left: 0.25rem;
padding-right: 0.5rem;
/* flex-grow, flex-shrink, flex-basis */
/* 左边div不扩展也不收缩,基础宽度为10% */
}

.fileViewMenu {
flex: 1;
height: 92vh;
/* 允许不含空格的单词在任何地方换行 */
word-break: break-all;
font-size: smaller;
}

.fileViewResult {
flex: 1;
overflow-x: auto;
overflow-y: auto;
padding: 0rem 0.5rem 0rem 1rem;
/* 控制代码块容器的 padding: 上、右、下、左 */
--p-tabs-tabpanel-padding: 0.35rem 0rem 0 0;
/* 右边div占据剩余空间 */
/* 可以省略flex-grow为1,因为默认值就是1 */

/* 选中标签页的底部块的高度 */
--p-tabs-active-bar-height: 3.2px;
}

.btn {
height: 2.4rem;
}
</style>
31 changes: 31 additions & 0 deletions os-checks/components/Print.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script setup lang="ts">
import Button from 'primevue/button';
import type { CheckerResult, FileTree } from '~/shared/file-tree';
import type { Get } from '~/shared/file-tree/utils';

type Props = {
get: Get, tmp: string,
tabs: CheckerResult[],
selectedTab: string,
fileTree: FileTree,
};
const props = defineProps<Props>();

watch(() => props.get, val => console.log("Print", val));
watch(() => props.fileTree, val => console.log("Print fileTree", val));
</script>

<template>
<Button>{{ props.tmp }}</Button>
<div>
fileTree.data.length: {{ props.fileTree.data.length }}
</div>
<div>
tabs: {{ props.tabs }}
</div>
<div>
selectedTab: {{ props.selectedTab }}
</div>

{{ props.get }}
</template>
15 changes: 6 additions & 9 deletions os-checks/components/TargetDropDown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,14 @@ function fetch() {
});
}

function change(path: string, params: any) {
// console.log("path =", path);
const excludes = ["/", "/repos", "/charts", "/target", "/workflows", "/testcases"];
if (excludes.findIndex(p => p === path) !== -1) {
visible.value = false;
return;
} else if (params) {
// console.log("path =", path);
function change(path: string, _params: any) {
const includes = ["/diagnostics"];
if (includes.findIndex(p => p === path) !== -1) {
visible.value = true;
fetch();
} else {
visible.value = false;
}
visible.value = true;
}
</script>

Expand Down
11 changes: 11 additions & 0 deletions os-checks/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions os-checks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"chart.js": "^4.4.5",
"chartjs-plugin-datalabels": "^2.2.0",
"dompurify": "^3.1.7",
"es-toolkit": "^1.32.0",
"highlight.js": "^11.10.0",
"nuxt": "^3.13.2",
"ofetch": "^1.4.1",
Expand Down
Loading