@galaxy-tool-util/gxwf-report-shell 0.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +55 -0
- package/dist/shell.css +1 -0
- package/dist/shell.iife.js +3216 -0
- package/package.json +47 -0
- package/src/CleanReport.vue +112 -0
- package/src/ExportReport.vue +171 -0
- package/src/LintReport.vue +90 -0
- package/src/RawJsonView.vue +28 -0
- package/src/ReportShell.vue +147 -0
- package/src/RoundtripReport.vue +130 -0
- package/src/ToolId.vue +19 -0
- package/src/TreeCleanReport.vue +111 -0
- package/src/TreeLintReport.vue +107 -0
- package/src/TreeRoundtripReport.vue +157 -0
- package/src/TreeValidationReport.vue +129 -0
- package/src/ValidationReport.vue +103 -0
- package/src/index.ts +14 -0
- package/src/shell.ts +42 -0
- package/src/toolId.ts +30 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="operation-report">
|
|
3
|
+
<div class="summary-row">
|
|
4
|
+
<Tag
|
|
5
|
+
:value="result.ok ? 'pass' : 'fail'"
|
|
6
|
+
:severity="result.ok ? 'success' : 'danger'"
|
|
7
|
+
class="status-tag"
|
|
8
|
+
/>
|
|
9
|
+
<span class="summary-line">{{ result.summary_line }}</span>
|
|
10
|
+
</div>
|
|
11
|
+
|
|
12
|
+
<Message v-if="result.error" severity="error" :closable="false">{{ result.error }}</Message>
|
|
13
|
+
|
|
14
|
+
<template v-if="result.conversion_failure_lines.length">
|
|
15
|
+
<h4 class="section-heading">Conversion Failures</h4>
|
|
16
|
+
<ul class="failure-list">
|
|
17
|
+
<li v-for="(line, i) in result.conversion_failure_lines" :key="i">
|
|
18
|
+
<code>{{ line }}</code>
|
|
19
|
+
</li>
|
|
20
|
+
</ul>
|
|
21
|
+
</template>
|
|
22
|
+
|
|
23
|
+
<template v-if="result.error_diffs.length">
|
|
24
|
+
<p class="section-heading"><Tag value="error" severity="danger" /> Diffs</p>
|
|
25
|
+
<DataTable :value="result.error_diffs" size="small">
|
|
26
|
+
<Column field="step_path" header="Step" />
|
|
27
|
+
<Column field="key_path" header="Key" />
|
|
28
|
+
<Column field="description" header="Description" />
|
|
29
|
+
</DataTable>
|
|
30
|
+
</template>
|
|
31
|
+
|
|
32
|
+
<template v-if="result.benign_diffs.length">
|
|
33
|
+
<p class="section-heading"><Tag value="benign" severity="secondary" /> Diffs</p>
|
|
34
|
+
<DataTable :value="result.benign_diffs" size="small">
|
|
35
|
+
<Column field="step_path" header="Step" />
|
|
36
|
+
<Column field="key_path" header="Key" />
|
|
37
|
+
<Column field="description" header="Description" />
|
|
38
|
+
</DataTable>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<Panel
|
|
42
|
+
v-if="report.before_content != null || report.after_content != null"
|
|
43
|
+
header="Workflow content"
|
|
44
|
+
:toggleable="true"
|
|
45
|
+
:collapsed="true"
|
|
46
|
+
>
|
|
47
|
+
<Tabs value="original">
|
|
48
|
+
<TabList>
|
|
49
|
+
<Tab value="original">Original (native)</Tab>
|
|
50
|
+
<Tab value="reimported">Re-imported (native)</Tab>
|
|
51
|
+
</TabList>
|
|
52
|
+
<TabPanels>
|
|
53
|
+
<TabPanel value="original">
|
|
54
|
+
<pre class="content-pre">{{ report.before_content ?? "(none)" }}</pre>
|
|
55
|
+
</TabPanel>
|
|
56
|
+
<TabPanel value="reimported">
|
|
57
|
+
<pre class="content-pre">{{ report.after_content ?? "(none)" }}</pre>
|
|
58
|
+
</TabPanel>
|
|
59
|
+
</TabPanels>
|
|
60
|
+
</Tabs>
|
|
61
|
+
</Panel>
|
|
62
|
+
</div>
|
|
63
|
+
</template>
|
|
64
|
+
|
|
65
|
+
<script setup lang="ts">
|
|
66
|
+
import { computed } from "vue";
|
|
67
|
+
import type { SingleRoundTripReport } from "@galaxy-tool-util/schema";
|
|
68
|
+
import DataTable from "primevue/datatable";
|
|
69
|
+
import Column from "primevue/column";
|
|
70
|
+
import Panel from "primevue/panel";
|
|
71
|
+
import Tab from "primevue/tab";
|
|
72
|
+
import TabList from "primevue/tablist";
|
|
73
|
+
import TabPanel from "primevue/tabpanel";
|
|
74
|
+
import TabPanels from "primevue/tabpanels";
|
|
75
|
+
import Tabs from "primevue/tabs";
|
|
76
|
+
import Tag from "primevue/tag";
|
|
77
|
+
import Message from "primevue/message";
|
|
78
|
+
|
|
79
|
+
const props = defineProps<{
|
|
80
|
+
report: SingleRoundTripReport;
|
|
81
|
+
}>();
|
|
82
|
+
|
|
83
|
+
const result = computed(() => props.report.result);
|
|
84
|
+
</script>
|
|
85
|
+
|
|
86
|
+
<style scoped>
|
|
87
|
+
.operation-report {
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: column;
|
|
90
|
+
gap: 0.75rem;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
.summary-row {
|
|
94
|
+
display: flex;
|
|
95
|
+
align-items: center;
|
|
96
|
+
gap: 0.75rem;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.summary-line {
|
|
100
|
+
font-size: 0.9rem;
|
|
101
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
.section-heading {
|
|
105
|
+
margin: 0.25rem 0 0;
|
|
106
|
+
font-size: 0.95rem;
|
|
107
|
+
display: flex;
|
|
108
|
+
align-items: center;
|
|
109
|
+
gap: 0.4rem;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.failure-list {
|
|
113
|
+
margin: 0;
|
|
114
|
+
padding-left: 1.25rem;
|
|
115
|
+
font-size: 0.85rem;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.content-pre {
|
|
119
|
+
margin: 0;
|
|
120
|
+
padding: 0.5rem;
|
|
121
|
+
font-size: 0.75rem;
|
|
122
|
+
background: var(--p-content-background);
|
|
123
|
+
border: 1px solid var(--p-content-border-color);
|
|
124
|
+
border-radius: 4px;
|
|
125
|
+
color: var(--p-text-color);
|
|
126
|
+
overflow: auto;
|
|
127
|
+
max-height: 500px;
|
|
128
|
+
white-space: pre;
|
|
129
|
+
}
|
|
130
|
+
</style>
|
package/src/ToolId.vue
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<span :title="toolId ?? undefined" class="tool-id">{{ label }}</span>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { computed } from "vue";
|
|
7
|
+
import { formatToolId } from "./toolId.js";
|
|
8
|
+
|
|
9
|
+
const props = defineProps<{ toolId: string | null }>();
|
|
10
|
+
|
|
11
|
+
const label = computed(() => formatToolId(props.toolId));
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
<style scoped>
|
|
15
|
+
.tool-id {
|
|
16
|
+
font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, monospace;
|
|
17
|
+
font-size: 0.85em;
|
|
18
|
+
}
|
|
19
|
+
</style>
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tree-report">
|
|
3
|
+
<p class="root-path">
|
|
4
|
+
Root: <code>{{ report.root }}</code>
|
|
5
|
+
</p>
|
|
6
|
+
<div class="summary-row">
|
|
7
|
+
<Tag
|
|
8
|
+
:value="`${report.summary.affected} affected`"
|
|
9
|
+
:severity="report.summary.affected > 0 ? 'warn' : 'secondary'"
|
|
10
|
+
/>
|
|
11
|
+
<Tag :value="`${report.summary.clean} clean`" severity="success" />
|
|
12
|
+
<Tag
|
|
13
|
+
:value="`${report.summary.total_keys} key${report.summary.total_keys !== 1 ? 's' : ''} removed`"
|
|
14
|
+
severity="secondary"
|
|
15
|
+
/>
|
|
16
|
+
<Tag
|
|
17
|
+
v-if="report.summary.errors > 0"
|
|
18
|
+
:value="`${report.summary.errors} error${report.summary.errors !== 1 ? 's' : ''}`"
|
|
19
|
+
severity="danger"
|
|
20
|
+
/>
|
|
21
|
+
<Tag
|
|
22
|
+
v-if="report.summary.skipped > 0"
|
|
23
|
+
:value="`${report.summary.skipped} skipped`"
|
|
24
|
+
severity="warn"
|
|
25
|
+
/>
|
|
26
|
+
</div>
|
|
27
|
+
|
|
28
|
+
<template v-for="cat in report.categories" :key="cat.name">
|
|
29
|
+
<h3 class="category-heading">
|
|
30
|
+
{{ cat.name }} <span class="category-count">({{ cat.results.length }})</span>
|
|
31
|
+
</h3>
|
|
32
|
+
<DataTable :value="cat.results" size="small" class="category-table">
|
|
33
|
+
<Column field="name" header="Workflow" />
|
|
34
|
+
<Column header="Status">
|
|
35
|
+
<template #body="{ data }: { data: WorkflowCleanResult }">
|
|
36
|
+
<Tag v-if="data.skipped_reason" value="SKIPPED" severity="warn" />
|
|
37
|
+
<Tag v-else-if="data.error" value="ERROR" severity="danger" />
|
|
38
|
+
<Tag
|
|
39
|
+
v-else-if="data.total_removed > 0"
|
|
40
|
+
:value="`${data.total_removed} removed`"
|
|
41
|
+
severity="warn"
|
|
42
|
+
/>
|
|
43
|
+
<Tag v-else value="clean" severity="success" />
|
|
44
|
+
</template>
|
|
45
|
+
</Column>
|
|
46
|
+
<Column header="Keys / Steps">
|
|
47
|
+
<template #body="{ data }: { data: WorkflowCleanResult }">
|
|
48
|
+
<span v-if="data.error" class="detail-note">{{ data.error }}</span>
|
|
49
|
+
<span v-else-if="data.skipped_reason" class="detail-note">{{
|
|
50
|
+
data.skipped_reason
|
|
51
|
+
}}</span>
|
|
52
|
+
<span v-else>
|
|
53
|
+
{{ data.total_removed }} key{{ data.total_removed !== 1 ? "s" : "" }},
|
|
54
|
+
{{ data.steps_affected }} step{{ data.steps_affected !== 1 ? "s" : "" }}
|
|
55
|
+
</span>
|
|
56
|
+
</template>
|
|
57
|
+
</Column>
|
|
58
|
+
</DataTable>
|
|
59
|
+
</template>
|
|
60
|
+
</div>
|
|
61
|
+
</template>
|
|
62
|
+
|
|
63
|
+
<script setup lang="ts">
|
|
64
|
+
import type { TreeCleanReport, WorkflowCleanResult } from "@galaxy-tool-util/schema";
|
|
65
|
+
import DataTable from "primevue/datatable";
|
|
66
|
+
import Column from "primevue/column";
|
|
67
|
+
import Tag from "primevue/tag";
|
|
68
|
+
|
|
69
|
+
defineProps<{ report: TreeCleanReport }>();
|
|
70
|
+
</script>
|
|
71
|
+
|
|
72
|
+
<style scoped>
|
|
73
|
+
.tree-report {
|
|
74
|
+
display: flex;
|
|
75
|
+
flex-direction: column;
|
|
76
|
+
gap: 1rem;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.root-path {
|
|
80
|
+
font-family: monospace;
|
|
81
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
82
|
+
margin: 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.summary-row {
|
|
86
|
+
display: flex;
|
|
87
|
+
gap: 0.5rem;
|
|
88
|
+
flex-wrap: wrap;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.category-heading {
|
|
92
|
+
font-size: 1rem;
|
|
93
|
+
font-weight: 600;
|
|
94
|
+
margin: 0;
|
|
95
|
+
color: var(--p-text-color, #212529);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.category-count {
|
|
99
|
+
font-weight: 400;
|
|
100
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.category-table {
|
|
104
|
+
margin-top: 0.25rem;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.detail-note {
|
|
108
|
+
font-style: italic;
|
|
109
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
110
|
+
}
|
|
111
|
+
</style>
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tree-report">
|
|
3
|
+
<p class="root-path">
|
|
4
|
+
Root: <code>{{ report.root }}</code>
|
|
5
|
+
</p>
|
|
6
|
+
<div class="summary-row">
|
|
7
|
+
<Tag
|
|
8
|
+
:value="`${report.summary.lint_errors} lint error${report.summary.lint_errors !== 1 ? 's' : ''}`"
|
|
9
|
+
:severity="report.summary.lint_errors > 0 ? 'danger' : 'success'"
|
|
10
|
+
/>
|
|
11
|
+
<Tag
|
|
12
|
+
:value="`${report.summary.lint_warnings} warning${report.summary.lint_warnings !== 1 ? 's' : ''}`"
|
|
13
|
+
:severity="report.summary.lint_warnings > 0 ? 'warn' : 'secondary'"
|
|
14
|
+
/>
|
|
15
|
+
<Tag
|
|
16
|
+
v-if="report.summary.errors > 0"
|
|
17
|
+
:value="`${report.summary.errors} file error${report.summary.errors !== 1 ? 's' : ''}`"
|
|
18
|
+
severity="danger"
|
|
19
|
+
/>
|
|
20
|
+
<Tag
|
|
21
|
+
v-if="report.summary.skipped > 0"
|
|
22
|
+
:value="`${report.summary.skipped} skipped`"
|
|
23
|
+
severity="warn"
|
|
24
|
+
/>
|
|
25
|
+
</div>
|
|
26
|
+
|
|
27
|
+
<template v-for="cat in report.categories" :key="cat.name">
|
|
28
|
+
<h3 class="category-heading">
|
|
29
|
+
{{ cat.name }} <span class="category-count">({{ cat.results.length }})</span>
|
|
30
|
+
</h3>
|
|
31
|
+
<DataTable :value="cat.results" size="small" class="category-table">
|
|
32
|
+
<Column field="name" header="Workflow" />
|
|
33
|
+
<Column header="Status">
|
|
34
|
+
<template #body="{ data }: { data: LintWorkflowResult }">
|
|
35
|
+
<Tag v-if="data.skipped_reason" value="SKIPPED" severity="warn" />
|
|
36
|
+
<Tag v-else-if="data.error" value="ERROR" severity="danger" />
|
|
37
|
+
<Tag
|
|
38
|
+
v-else-if="data.lint_errors > 0"
|
|
39
|
+
:value="`${data.lint_errors} error${data.lint_errors !== 1 ? 's' : ''}`"
|
|
40
|
+
severity="danger"
|
|
41
|
+
/>
|
|
42
|
+
<Tag v-else value="OK" severity="success" />
|
|
43
|
+
</template>
|
|
44
|
+
</Column>
|
|
45
|
+
<Column header="Lint">
|
|
46
|
+
<template #body="{ data }: { data: LintWorkflowResult }">
|
|
47
|
+
<span v-if="data.error" class="detail-note">{{ data.error }}</span>
|
|
48
|
+
<span v-else-if="data.skipped_reason" class="detail-note">{{
|
|
49
|
+
data.skipped_reason
|
|
50
|
+
}}</span>
|
|
51
|
+
<span v-else>{{ data.lint_errors }} err, {{ data.lint_warnings }} warn</span>
|
|
52
|
+
</template>
|
|
53
|
+
</Column>
|
|
54
|
+
</DataTable>
|
|
55
|
+
</template>
|
|
56
|
+
</div>
|
|
57
|
+
</template>
|
|
58
|
+
|
|
59
|
+
<script setup lang="ts">
|
|
60
|
+
import type { LintTreeReport, LintWorkflowResult } from "@galaxy-tool-util/schema";
|
|
61
|
+
import DataTable from "primevue/datatable";
|
|
62
|
+
import Column from "primevue/column";
|
|
63
|
+
import Tag from "primevue/tag";
|
|
64
|
+
|
|
65
|
+
defineProps<{ report: LintTreeReport }>();
|
|
66
|
+
</script>
|
|
67
|
+
|
|
68
|
+
<style scoped>
|
|
69
|
+
.tree-report {
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
gap: 1rem;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
.root-path {
|
|
76
|
+
font-family: monospace;
|
|
77
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
78
|
+
margin: 0;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.summary-row {
|
|
82
|
+
display: flex;
|
|
83
|
+
gap: 0.5rem;
|
|
84
|
+
flex-wrap: wrap;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.category-heading {
|
|
88
|
+
font-size: 1rem;
|
|
89
|
+
font-weight: 600;
|
|
90
|
+
margin: 0;
|
|
91
|
+
color: var(--p-text-color, #212529);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.category-count {
|
|
95
|
+
font-weight: 400;
|
|
96
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.category-table {
|
|
100
|
+
margin-top: 0.25rem;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.detail-note {
|
|
104
|
+
font-style: italic;
|
|
105
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
106
|
+
}
|
|
107
|
+
</style>
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tree-report">
|
|
3
|
+
<p class="root-path">
|
|
4
|
+
Root: <code>{{ report.root }}</code>
|
|
5
|
+
</p>
|
|
6
|
+
<div class="summary-row">
|
|
7
|
+
<Tag :value="`${report.summary.clean} clean`" severity="success" />
|
|
8
|
+
<Tag
|
|
9
|
+
v-if="report.summary.benign_only > 0"
|
|
10
|
+
:value="`${report.summary.benign_only} benign`"
|
|
11
|
+
severity="warn"
|
|
12
|
+
/>
|
|
13
|
+
<Tag
|
|
14
|
+
v-if="report.summary.fail > 0"
|
|
15
|
+
:value="`${report.summary.fail} FAIL`"
|
|
16
|
+
severity="danger"
|
|
17
|
+
/>
|
|
18
|
+
<Tag
|
|
19
|
+
v-if="report.summary.error > 0"
|
|
20
|
+
:value="`${report.summary.error} error`"
|
|
21
|
+
severity="danger"
|
|
22
|
+
/>
|
|
23
|
+
<Tag
|
|
24
|
+
v-if="report.summary.skipped > 0"
|
|
25
|
+
:value="`${report.summary.skipped} skipped`"
|
|
26
|
+
severity="secondary"
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<template v-for="cat in categories" :key="cat.name">
|
|
31
|
+
<h3 class="category-heading">
|
|
32
|
+
{{ cat.name }} <span class="category-count">({{ cat.workflows.length }})</span>
|
|
33
|
+
</h3>
|
|
34
|
+
<DataTable :value="cat.workflows" size="small" class="category-table">
|
|
35
|
+
<Column field="workflow_path" header="Workflow" />
|
|
36
|
+
<Column header="Status">
|
|
37
|
+
<template #body="{ data }: { data: RoundTripValidationResult }">
|
|
38
|
+
<Tag v-if="data.skipped_reason" value="SKIPPED" severity="secondary" />
|
|
39
|
+
<Tag v-else-if="data.error" value="ERROR" severity="danger" />
|
|
40
|
+
<Tag
|
|
41
|
+
v-else-if="data.status === 'ok' && data.benign_diffs.length === 0"
|
|
42
|
+
value="clean"
|
|
43
|
+
severity="success"
|
|
44
|
+
/>
|
|
45
|
+
<Tag v-else-if="data.status === 'ok'" value="benign" severity="warn" />
|
|
46
|
+
<Tag v-else value="FAIL" severity="danger" />
|
|
47
|
+
</template>
|
|
48
|
+
</Column>
|
|
49
|
+
<Column header="Details">
|
|
50
|
+
<template #body="{ data }: { data: RoundTripValidationResult }">
|
|
51
|
+
<span v-if="data.error" class="detail-note">{{ data.error }}</span>
|
|
52
|
+
<span v-else-if="data.skipped_reason" class="detail-note">{{
|
|
53
|
+
data.skipped_reason
|
|
54
|
+
}}</span>
|
|
55
|
+
<span v-else>
|
|
56
|
+
<span v-if="data.error_diffs.length"
|
|
57
|
+
>{{ data.error_diffs.length }} real diff{{
|
|
58
|
+
data.error_diffs.length !== 1 ? "s" : ""
|
|
59
|
+
}}</span
|
|
60
|
+
>
|
|
61
|
+
<span v-if="data.benign_diffs.length && data.error_diffs.length">, </span>
|
|
62
|
+
<span v-if="data.benign_diffs.length">{{ data.benign_diffs.length }} benign</span>
|
|
63
|
+
<span v-if="!data.error_diffs.length && !data.benign_diffs.length" class="detail-note"
|
|
64
|
+
>—</span
|
|
65
|
+
>
|
|
66
|
+
</span>
|
|
67
|
+
</template>
|
|
68
|
+
</Column>
|
|
69
|
+
</DataTable>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<template v-if="report.tool_failure_modes.length">
|
|
73
|
+
<h3 class="category-heading">Tool Failure Modes</h3>
|
|
74
|
+
<DataTable :value="report.tool_failure_modes" size="small">
|
|
75
|
+
<Column header="Tool">
|
|
76
|
+
<template #body="{ data }: { data: ToolFailureMode }">
|
|
77
|
+
<ToolId :tool-id="data.tool_id" />
|
|
78
|
+
</template>
|
|
79
|
+
</Column>
|
|
80
|
+
<Column field="failure_class" header="Failure Class" />
|
|
81
|
+
<Column field="count" header="Count" />
|
|
82
|
+
</DataTable>
|
|
83
|
+
</template>
|
|
84
|
+
</div>
|
|
85
|
+
</template>
|
|
86
|
+
|
|
87
|
+
<script setup lang="ts">
|
|
88
|
+
import { computed } from "vue";
|
|
89
|
+
import type {
|
|
90
|
+
RoundTripTreeReport,
|
|
91
|
+
RoundTripValidationResult,
|
|
92
|
+
ToolFailureMode,
|
|
93
|
+
} from "@galaxy-tool-util/schema";
|
|
94
|
+
import DataTable from "primevue/datatable";
|
|
95
|
+
import Column from "primevue/column";
|
|
96
|
+
import Tag from "primevue/tag";
|
|
97
|
+
import ToolId from "./ToolId.vue";
|
|
98
|
+
|
|
99
|
+
const props = defineProps<{ report: RoundTripTreeReport }>();
|
|
100
|
+
|
|
101
|
+
const categories = computed(() => {
|
|
102
|
+
const groups = new Map<string, RoundTripValidationResult[]>();
|
|
103
|
+
for (const wf of props.report.workflows) {
|
|
104
|
+
const cat = wf.category || "(root)";
|
|
105
|
+
let list = groups.get(cat);
|
|
106
|
+
if (!list) {
|
|
107
|
+
list = [];
|
|
108
|
+
groups.set(cat, list);
|
|
109
|
+
}
|
|
110
|
+
list.push(wf);
|
|
111
|
+
}
|
|
112
|
+
return Array.from(groups.entries())
|
|
113
|
+
.sort(([a], [b]) => a.localeCompare(b))
|
|
114
|
+
.map(([name, workflows]) => ({ name, workflows }));
|
|
115
|
+
});
|
|
116
|
+
</script>
|
|
117
|
+
|
|
118
|
+
<style scoped>
|
|
119
|
+
.tree-report {
|
|
120
|
+
display: flex;
|
|
121
|
+
flex-direction: column;
|
|
122
|
+
gap: 1rem;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.root-path {
|
|
126
|
+
font-family: monospace;
|
|
127
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
128
|
+
margin: 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
.summary-row {
|
|
132
|
+
display: flex;
|
|
133
|
+
gap: 0.5rem;
|
|
134
|
+
flex-wrap: wrap;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
.category-heading {
|
|
138
|
+
font-size: 1rem;
|
|
139
|
+
font-weight: 600;
|
|
140
|
+
margin: 0;
|
|
141
|
+
color: var(--p-text-color, #212529);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.category-count {
|
|
145
|
+
font-weight: 400;
|
|
146
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.category-table {
|
|
150
|
+
margin-top: 0.25rem;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.detail-note {
|
|
154
|
+
font-style: italic;
|
|
155
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
156
|
+
}
|
|
157
|
+
</style>
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="tree-report">
|
|
3
|
+
<p class="root-path">
|
|
4
|
+
Root: <code>{{ report.root }}</code>
|
|
5
|
+
</p>
|
|
6
|
+
<div class="summary-row">
|
|
7
|
+
<Tag :value="`${report.summary.ok} OK`" severity="success" />
|
|
8
|
+
<Tag
|
|
9
|
+
v-if="report.summary.fail > 0"
|
|
10
|
+
:value="`${report.summary.fail} FAIL`"
|
|
11
|
+
severity="danger"
|
|
12
|
+
/>
|
|
13
|
+
<Tag
|
|
14
|
+
v-if="report.summary.skip > 0"
|
|
15
|
+
:value="`${report.summary.skip} skip`"
|
|
16
|
+
severity="secondary"
|
|
17
|
+
/>
|
|
18
|
+
<Tag
|
|
19
|
+
v-if="report.summary.error > 0"
|
|
20
|
+
:value="`${report.summary.error} error`"
|
|
21
|
+
severity="danger"
|
|
22
|
+
/>
|
|
23
|
+
<Tag
|
|
24
|
+
v-if="report.summary.skipped > 0"
|
|
25
|
+
:value="`${report.summary.skipped} skipped`"
|
|
26
|
+
severity="warn"
|
|
27
|
+
/>
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
<template v-for="cat in report.categories" :key="cat.name">
|
|
31
|
+
<h3 class="category-heading">
|
|
32
|
+
{{ cat.name }} <span class="category-count">({{ cat.results.length }})</span>
|
|
33
|
+
</h3>
|
|
34
|
+
<DataTable :value="cat.results" size="small" class="category-table">
|
|
35
|
+
<Column field="name" header="Workflow" />
|
|
36
|
+
<Column header="Status">
|
|
37
|
+
<template #body="{ data }: { data: WorkflowValidationResult }">
|
|
38
|
+
<Tag v-if="data.skipped_reason" value="SKIPPED" severity="warn" />
|
|
39
|
+
<Tag v-else-if="data.error" value="ERROR" severity="danger" />
|
|
40
|
+
<Tag
|
|
41
|
+
v-else-if="data.summary && data.summary.fail > 0"
|
|
42
|
+
:value="`${data.summary.fail} FAIL`"
|
|
43
|
+
severity="danger"
|
|
44
|
+
/>
|
|
45
|
+
<Tag v-else value="OK" severity="success" />
|
|
46
|
+
</template>
|
|
47
|
+
</Column>
|
|
48
|
+
<Column header="Steps">
|
|
49
|
+
<template #body="{ data }: { data: WorkflowValidationResult }">
|
|
50
|
+
<span v-if="data.summary">
|
|
51
|
+
{{ data.summary.ok }} OK
|
|
52
|
+
<span v-if="data.summary.fail"> / {{ data.summary.fail }} FAIL</span>
|
|
53
|
+
<span v-if="data.summary.skip"> / {{ data.summary.skip }} skip</span>
|
|
54
|
+
</span>
|
|
55
|
+
<span v-else-if="data.error" class="detail-note">{{ data.error }}</span>
|
|
56
|
+
<span v-else-if="data.skipped_reason" class="detail-note">{{
|
|
57
|
+
data.skipped_reason
|
|
58
|
+
}}</span>
|
|
59
|
+
</template>
|
|
60
|
+
</Column>
|
|
61
|
+
</DataTable>
|
|
62
|
+
</template>
|
|
63
|
+
|
|
64
|
+
<template v-if="report.all_failures.length">
|
|
65
|
+
<h3 class="category-heading">Failure Details</h3>
|
|
66
|
+
<DataTable :value="report.all_failures" size="small">
|
|
67
|
+
<Column field="workflow" header="Workflow" />
|
|
68
|
+
<Column field="step" header="Step" />
|
|
69
|
+
<Column header="Tool">
|
|
70
|
+
<template #body="{ data }: { data: { tool_id: string | null } }">
|
|
71
|
+
<ToolId :tool-id="data.tool_id" />
|
|
72
|
+
</template>
|
|
73
|
+
</Column>
|
|
74
|
+
<Column field="message" header="Message" />
|
|
75
|
+
</DataTable>
|
|
76
|
+
</template>
|
|
77
|
+
</div>
|
|
78
|
+
</template>
|
|
79
|
+
|
|
80
|
+
<script setup lang="ts">
|
|
81
|
+
import type { TreeValidationReport, WorkflowValidationResult } from "@galaxy-tool-util/schema";
|
|
82
|
+
import DataTable from "primevue/datatable";
|
|
83
|
+
import Column from "primevue/column";
|
|
84
|
+
import Tag from "primevue/tag";
|
|
85
|
+
import ToolId from "./ToolId.vue";
|
|
86
|
+
|
|
87
|
+
defineProps<{ report: TreeValidationReport }>();
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<style scoped>
|
|
91
|
+
.tree-report {
|
|
92
|
+
display: flex;
|
|
93
|
+
flex-direction: column;
|
|
94
|
+
gap: 1rem;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.root-path {
|
|
98
|
+
font-family: monospace;
|
|
99
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
100
|
+
margin: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.summary-row {
|
|
104
|
+
display: flex;
|
|
105
|
+
gap: 0.5rem;
|
|
106
|
+
flex-wrap: wrap;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
.category-heading {
|
|
110
|
+
font-size: 1rem;
|
|
111
|
+
font-weight: 600;
|
|
112
|
+
margin: 0;
|
|
113
|
+
color: var(--p-text-color, #212529);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.category-count {
|
|
117
|
+
font-weight: 400;
|
|
118
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.category-table {
|
|
122
|
+
margin-top: 0.25rem;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.detail-note {
|
|
126
|
+
font-style: italic;
|
|
127
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
128
|
+
}
|
|
129
|
+
</style>
|