@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
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@galaxy-tool-util/gxwf-report-shell",
|
|
3
|
+
"version": "0.0.0",
|
|
4
|
+
"description": "Pre-built Vue 3 Galaxy workflow report components for CDN delivery",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": {
|
|
7
|
+
".": {
|
|
8
|
+
"types": "./src/index.ts",
|
|
9
|
+
"import": "./src/index.ts"
|
|
10
|
+
},
|
|
11
|
+
"./*.vue": "./src/*.vue"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"src",
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md",
|
|
17
|
+
"LICENSE"
|
|
18
|
+
],
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"@primevue/themes": "^4.3.0",
|
|
21
|
+
"primevue": "^4.3.0",
|
|
22
|
+
"vue": "^3.5.0",
|
|
23
|
+
"@galaxy-tool-util/schema": "0.2.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@vitejs/plugin-vue": "^5.2.0",
|
|
27
|
+
"vite": "^6.2.0",
|
|
28
|
+
"vue-tsc": "^2.2.0"
|
|
29
|
+
},
|
|
30
|
+
"repository": {
|
|
31
|
+
"type": "git",
|
|
32
|
+
"url": "https://github.com/jmchilton/galaxy-tool-util-ts",
|
|
33
|
+
"directory": "packages/gxwf-report-shell"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public",
|
|
37
|
+
"provenance": true
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"scripts": {
|
|
41
|
+
"build": "vite build --config vite.config.shell.ts",
|
|
42
|
+
"typecheck": "vue-tsc --noEmit",
|
|
43
|
+
"lint": "eslint src/",
|
|
44
|
+
"format": "prettier --check 'src/**/*.{ts,vue}'",
|
|
45
|
+
"format-fix": "prettier --write 'src/**/*.{ts,vue}'"
|
|
46
|
+
}
|
|
47
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="operation-report">
|
|
3
|
+
<div class="summary-row">
|
|
4
|
+
<Tag
|
|
5
|
+
:value="`${report.total_removed} key${report.total_removed !== 1 ? 's' : ''} removed`"
|
|
6
|
+
:severity="report.total_removed > 0 ? 'warn' : 'success'"
|
|
7
|
+
/>
|
|
8
|
+
<Tag
|
|
9
|
+
:value="`${report.steps_with_removals} step${report.steps_with_removals !== 1 ? 's' : ''} affected`"
|
|
10
|
+
severity="secondary"
|
|
11
|
+
/>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<DataTable :value="report.results" size="small">
|
|
15
|
+
<Column field="step" header="Step" />
|
|
16
|
+
<Column header="Tool">
|
|
17
|
+
<template #body="{ data }: { data: CleanStepResult }">
|
|
18
|
+
<ToolId :tool-id="data.tool_id" />
|
|
19
|
+
</template>
|
|
20
|
+
</Column>
|
|
21
|
+
<Column header="Removed Keys">
|
|
22
|
+
<template #body="{ data }: { data: CleanStepResult }">
|
|
23
|
+
<span v-if="data.skipped" class="skip-reason">{{ data.skip_reason || "skipped" }}</span>
|
|
24
|
+
<span v-else-if="data.removed_keys.length === 0" class="no-changes">—</span>
|
|
25
|
+
<ul v-else class="key-list">
|
|
26
|
+
<li v-for="(k, i) in data.removed_keys" :key="i">
|
|
27
|
+
<code>{{ k }}</code>
|
|
28
|
+
</li>
|
|
29
|
+
</ul>
|
|
30
|
+
</template>
|
|
31
|
+
</Column>
|
|
32
|
+
</DataTable>
|
|
33
|
+
|
|
34
|
+
<Panel
|
|
35
|
+
v-if="report.before_content != null || report.after_content != null"
|
|
36
|
+
header="Workflow content"
|
|
37
|
+
:toggleable="true"
|
|
38
|
+
:collapsed="true"
|
|
39
|
+
>
|
|
40
|
+
<Tabs value="before">
|
|
41
|
+
<TabList>
|
|
42
|
+
<Tab value="before">Before</Tab>
|
|
43
|
+
<Tab value="after">After</Tab>
|
|
44
|
+
</TabList>
|
|
45
|
+
<TabPanels>
|
|
46
|
+
<TabPanel value="before">
|
|
47
|
+
<pre class="content-pre">{{ report.before_content ?? "(none)" }}</pre>
|
|
48
|
+
</TabPanel>
|
|
49
|
+
<TabPanel value="after">
|
|
50
|
+
<pre class="content-pre">{{ report.after_content ?? "(none)" }}</pre>
|
|
51
|
+
</TabPanel>
|
|
52
|
+
</TabPanels>
|
|
53
|
+
</Tabs>
|
|
54
|
+
</Panel>
|
|
55
|
+
</div>
|
|
56
|
+
</template>
|
|
57
|
+
|
|
58
|
+
<script setup lang="ts">
|
|
59
|
+
import DataTable from "primevue/datatable";
|
|
60
|
+
import Panel from "primevue/panel";
|
|
61
|
+
import Tab from "primevue/tab";
|
|
62
|
+
import TabList from "primevue/tablist";
|
|
63
|
+
import TabPanel from "primevue/tabpanel";
|
|
64
|
+
import TabPanels from "primevue/tabpanels";
|
|
65
|
+
import Tabs from "primevue/tabs";
|
|
66
|
+
import type { SingleCleanReport, CleanStepResult } from "@galaxy-tool-util/schema";
|
|
67
|
+
import Column from "primevue/column";
|
|
68
|
+
import Tag from "primevue/tag";
|
|
69
|
+
import ToolId from "./ToolId.vue";
|
|
70
|
+
|
|
71
|
+
defineProps<{
|
|
72
|
+
report: SingleCleanReport;
|
|
73
|
+
}>();
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<style scoped>
|
|
77
|
+
.operation-report {
|
|
78
|
+
display: flex;
|
|
79
|
+
flex-direction: column;
|
|
80
|
+
gap: 0.75rem;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
.summary-row {
|
|
84
|
+
display: flex;
|
|
85
|
+
gap: 0.5rem;
|
|
86
|
+
flex-wrap: wrap;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.key-list {
|
|
90
|
+
margin: 0;
|
|
91
|
+
padding-left: 1.25rem;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.skip-reason,
|
|
95
|
+
.no-changes {
|
|
96
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
97
|
+
font-style: italic;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
.content-pre {
|
|
101
|
+
margin: 0;
|
|
102
|
+
padding: 0.5rem;
|
|
103
|
+
font-size: 0.75rem;
|
|
104
|
+
background: var(--p-content-background);
|
|
105
|
+
border: 1px solid var(--p-content-border-color);
|
|
106
|
+
border-radius: 4px;
|
|
107
|
+
color: var(--p-text-color);
|
|
108
|
+
overflow: auto;
|
|
109
|
+
max-height: 500px;
|
|
110
|
+
white-space: pre;
|
|
111
|
+
}
|
|
112
|
+
</style>
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="operation-report">
|
|
3
|
+
<div class="summary-row">
|
|
4
|
+
<Tag :value="`${sourceFormatLabel} → ${targetFormatLabel}`" severity="info" />
|
|
5
|
+
<Tag v-if="result.dry_run" value="Dry run" severity="warn" />
|
|
6
|
+
<Tag v-if="removedPath" :value="`Removes ${removedPath}`" severity="danger" />
|
|
7
|
+
<Tag :value="summaryLabel" :severity="allOk ? 'success' : 'warn'" />
|
|
8
|
+
</div>
|
|
9
|
+
|
|
10
|
+
<div class="path-row">
|
|
11
|
+
<div>
|
|
12
|
+
<span class="path-label">Source:</span> <code>{{ result.source_path }}</code>
|
|
13
|
+
</div>
|
|
14
|
+
<div>
|
|
15
|
+
<span class="path-label">Output:</span> <code>{{ result.output_path }}</code>
|
|
16
|
+
</div>
|
|
17
|
+
<div v-if="removedPath">
|
|
18
|
+
<span class="path-label">Removed:</span> <code>{{ removedPath }}</code>
|
|
19
|
+
</div>
|
|
20
|
+
</div>
|
|
21
|
+
|
|
22
|
+
<DataTable v-if="stepRows.length > 0" :value="stepRows" size="small">
|
|
23
|
+
<Column field="step_id" header="Step" />
|
|
24
|
+
<Column field="step_label" header="Label">
|
|
25
|
+
<template #body="{ data }: { data: ExportStepRow }">
|
|
26
|
+
<span v-if="data.step_label">{{ data.step_label }}</span>
|
|
27
|
+
<span v-else class="muted">—</span>
|
|
28
|
+
</template>
|
|
29
|
+
</Column>
|
|
30
|
+
<Column header="Tool">
|
|
31
|
+
<template #body="{ data }: { data: ExportStepRow }">
|
|
32
|
+
<ToolId v-if="data.tool_id" :tool-id="data.tool_id" />
|
|
33
|
+
<span v-else class="muted">—</span>
|
|
34
|
+
</template>
|
|
35
|
+
</Column>
|
|
36
|
+
<Column header="Status">
|
|
37
|
+
<template #body="{ data }: { data: ExportStepRow }">
|
|
38
|
+
<Tag
|
|
39
|
+
:value="data.ok ? 'OK' : (data.error ?? 'Failed')"
|
|
40
|
+
:severity="data.ok ? 'success' : 'danger'"
|
|
41
|
+
/>
|
|
42
|
+
</template>
|
|
43
|
+
</Column>
|
|
44
|
+
</DataTable>
|
|
45
|
+
|
|
46
|
+
<Panel
|
|
47
|
+
v-if="result.content != null"
|
|
48
|
+
header="Converted content"
|
|
49
|
+
:toggleable="true"
|
|
50
|
+
:collapsed="true"
|
|
51
|
+
>
|
|
52
|
+
<pre class="content-pre">{{ result.content }}</pre>
|
|
53
|
+
</Panel>
|
|
54
|
+
</div>
|
|
55
|
+
</template>
|
|
56
|
+
|
|
57
|
+
<script setup lang="ts">
|
|
58
|
+
import { computed } from "vue";
|
|
59
|
+
import DataTable from "primevue/datatable";
|
|
60
|
+
import Column from "primevue/column";
|
|
61
|
+
import Panel from "primevue/panel";
|
|
62
|
+
import Tag from "primevue/tag";
|
|
63
|
+
import type {
|
|
64
|
+
ExportResult,
|
|
65
|
+
ConvertResult,
|
|
66
|
+
SingleExportReport,
|
|
67
|
+
ToNativeResult,
|
|
68
|
+
StepEncodeStatus,
|
|
69
|
+
} from "@galaxy-tool-util/schema";
|
|
70
|
+
import ToolId from "./ToolId.vue";
|
|
71
|
+
|
|
72
|
+
interface ExportStepRow {
|
|
73
|
+
step_id: string;
|
|
74
|
+
step_label: string | null;
|
|
75
|
+
tool_id: string | null;
|
|
76
|
+
ok: boolean;
|
|
77
|
+
error: string | null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const props = defineProps<{
|
|
81
|
+
result: ExportResult | ConvertResult;
|
|
82
|
+
}>();
|
|
83
|
+
|
|
84
|
+
const removedPath = computed(() =>
|
|
85
|
+
"removed_path" in props.result ? props.result.removed_path : null,
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const isToNative = computed(() => props.result.target_format === "native");
|
|
89
|
+
|
|
90
|
+
const sourceFormatLabel = computed(() =>
|
|
91
|
+
props.result.source_format === "native" ? "Native (.ga)" : "Format2 (.gxwf.yml)",
|
|
92
|
+
);
|
|
93
|
+
const targetFormatLabel = computed(() =>
|
|
94
|
+
props.result.target_format === "native" ? "Native (.ga)" : "Format2 (.gxwf.yml)",
|
|
95
|
+
);
|
|
96
|
+
|
|
97
|
+
const stepRows = computed<ExportStepRow[]>(() => {
|
|
98
|
+
if (isToNative.value) {
|
|
99
|
+
const r = props.result.report as ToNativeResult;
|
|
100
|
+
return (r.steps ?? []).map((s: StepEncodeStatus) => ({
|
|
101
|
+
step_id: s.step_id,
|
|
102
|
+
step_label: s.step_label,
|
|
103
|
+
tool_id: s.tool_id,
|
|
104
|
+
ok: s.encoded,
|
|
105
|
+
error: s.error,
|
|
106
|
+
}));
|
|
107
|
+
}
|
|
108
|
+
// Native → format2 report (SingleExportReport) carries counts but no per-step list.
|
|
109
|
+
return [];
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
const allOk = computed(() => {
|
|
113
|
+
if (isToNative.value) {
|
|
114
|
+
return (props.result.report as ToNativeResult).all_encoded;
|
|
115
|
+
}
|
|
116
|
+
return (props.result.report as SingleExportReport).ok;
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
const summaryLabel = computed(() => {
|
|
120
|
+
if (isToNative.value) {
|
|
121
|
+
return (props.result.report as ToNativeResult).summary;
|
|
122
|
+
}
|
|
123
|
+
const r = props.result.report as SingleExportReport;
|
|
124
|
+
const total = r.steps_converted + r.steps_fallback;
|
|
125
|
+
return `${r.steps_converted}/${total} step${total !== 1 ? "s" : ""} converted`;
|
|
126
|
+
});
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<style scoped>
|
|
130
|
+
.operation-report {
|
|
131
|
+
display: flex;
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
gap: 0.75rem;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.summary-row {
|
|
137
|
+
display: flex;
|
|
138
|
+
gap: 0.5rem;
|
|
139
|
+
flex-wrap: wrap;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.path-row {
|
|
143
|
+
display: flex;
|
|
144
|
+
flex-direction: column;
|
|
145
|
+
gap: 0.25rem;
|
|
146
|
+
font-size: 0.9rem;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
.path-label {
|
|
150
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
151
|
+
margin-right: 0.25rem;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
.muted {
|
|
155
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
156
|
+
font-style: italic;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
.content-pre {
|
|
160
|
+
margin: 0;
|
|
161
|
+
padding: 0.5rem;
|
|
162
|
+
font-size: 0.75rem;
|
|
163
|
+
background: var(--p-content-background);
|
|
164
|
+
border: 1px solid var(--p-content-border-color);
|
|
165
|
+
border-radius: 4px;
|
|
166
|
+
color: var(--p-text-color);
|
|
167
|
+
overflow: auto;
|
|
168
|
+
max-height: 500px;
|
|
169
|
+
white-space: pre;
|
|
170
|
+
}
|
|
171
|
+
</style>
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="operation-report">
|
|
3
|
+
<template v-if="structureErrors.length || encodingErrors.length">
|
|
4
|
+
<Message severity="error" :closable="false">
|
|
5
|
+
<ul class="error-list">
|
|
6
|
+
<li v-for="(e, i) in structureErrors" :key="'s' + i">{{ e }}</li>
|
|
7
|
+
<li v-for="(e, i) in encodingErrors" :key="'e' + i">{{ e }}</li>
|
|
8
|
+
</ul>
|
|
9
|
+
</Message>
|
|
10
|
+
</template>
|
|
11
|
+
|
|
12
|
+
<div class="summary-row">
|
|
13
|
+
<Tag
|
|
14
|
+
:value="`${report.lint_errors} error${report.lint_errors !== 1 ? 's' : ''}`"
|
|
15
|
+
:severity="report.lint_errors > 0 ? 'danger' : 'success'"
|
|
16
|
+
/>
|
|
17
|
+
<Tag
|
|
18
|
+
:value="`${report.lint_warnings} warning${report.lint_warnings !== 1 ? 's' : ''}`"
|
|
19
|
+
:severity="report.lint_warnings > 0 ? 'warn' : 'secondary'"
|
|
20
|
+
/>
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<DataTable :value="report.results" size="small" class="results-table">
|
|
24
|
+
<Column field="step" header="Step" />
|
|
25
|
+
<Column header="Tool">
|
|
26
|
+
<template #body="{ data }: { data: ValidationStepResult }">
|
|
27
|
+
<ToolId :tool-id="data.tool_id" />
|
|
28
|
+
</template>
|
|
29
|
+
</Column>
|
|
30
|
+
<Column header="Status">
|
|
31
|
+
<template #body="{ data }: { data: ValidationStepResult }">
|
|
32
|
+
<Tag :value="data.status" :severity="statusSeverity(data.status)" />
|
|
33
|
+
</template>
|
|
34
|
+
</Column>
|
|
35
|
+
<Column header="Errors">
|
|
36
|
+
<template #body="{ data }: { data: ValidationStepResult }">
|
|
37
|
+
<ul v-if="data.errors.length" class="error-list">
|
|
38
|
+
<li v-for="(e, i) in data.errors" :key="i">{{ e }}</li>
|
|
39
|
+
</ul>
|
|
40
|
+
</template>
|
|
41
|
+
</Column>
|
|
42
|
+
</DataTable>
|
|
43
|
+
</div>
|
|
44
|
+
</template>
|
|
45
|
+
|
|
46
|
+
<script setup lang="ts">
|
|
47
|
+
import { computed } from "vue";
|
|
48
|
+
import type { SingleLintReport, ValidationStepResult } from "@galaxy-tool-util/schema";
|
|
49
|
+
import DataTable from "primevue/datatable";
|
|
50
|
+
import Column from "primevue/column";
|
|
51
|
+
import Tag from "primevue/tag";
|
|
52
|
+
import Message from "primevue/message";
|
|
53
|
+
import ToolId from "./ToolId.vue";
|
|
54
|
+
|
|
55
|
+
const props = defineProps<{
|
|
56
|
+
report: SingleLintReport;
|
|
57
|
+
}>();
|
|
58
|
+
|
|
59
|
+
const structureErrors = computed(() => props.report.structure_errors ?? []);
|
|
60
|
+
const encodingErrors = computed(() => props.report.encoding_errors ?? []);
|
|
61
|
+
|
|
62
|
+
function statusSeverity(status: ValidationStepResult["status"]) {
|
|
63
|
+
if (status === "ok") return "success";
|
|
64
|
+
if (status === "fail") return "danger";
|
|
65
|
+
return "secondary";
|
|
66
|
+
}
|
|
67
|
+
</script>
|
|
68
|
+
|
|
69
|
+
<style scoped>
|
|
70
|
+
.operation-report {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
gap: 0.75rem;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.summary-row {
|
|
77
|
+
display: flex;
|
|
78
|
+
gap: 0.5rem;
|
|
79
|
+
flex-wrap: wrap;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.results-table {
|
|
83
|
+
margin-top: 0.5rem;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.error-list {
|
|
87
|
+
margin: 0;
|
|
88
|
+
padding-left: 1.25rem;
|
|
89
|
+
}
|
|
90
|
+
</style>
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<pre class="raw-json"><code>{{ formatted }}</code></pre>
|
|
3
|
+
</template>
|
|
4
|
+
|
|
5
|
+
<script setup lang="ts">
|
|
6
|
+
import { computed } from "vue";
|
|
7
|
+
|
|
8
|
+
const props = defineProps<{ data: unknown }>();
|
|
9
|
+
|
|
10
|
+
const formatted = computed(() => JSON.stringify(props.data, null, 2));
|
|
11
|
+
</script>
|
|
12
|
+
|
|
13
|
+
<style scoped>
|
|
14
|
+
.raw-json {
|
|
15
|
+
margin: 0;
|
|
16
|
+
padding: 1rem;
|
|
17
|
+
overflow: auto;
|
|
18
|
+
background: var(--p-content-background);
|
|
19
|
+
border: 1px solid var(--p-content-border-color);
|
|
20
|
+
border-radius: 6px;
|
|
21
|
+
font-family: ui-monospace, "Cascadia Code", "Source Code Pro", Menlo, Consolas, monospace;
|
|
22
|
+
font-size: 0.85rem;
|
|
23
|
+
line-height: 1.5;
|
|
24
|
+
color: var(--p-text-color);
|
|
25
|
+
white-space: pre;
|
|
26
|
+
max-height: 70vh;
|
|
27
|
+
}
|
|
28
|
+
</style>
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div class="gxwf-report-shell">
|
|
3
|
+
<header class="report-header">
|
|
4
|
+
<span class="report-type">{{ typeLabel }}</span>
|
|
5
|
+
<span v-if="workflowPath" class="report-path">{{ workflowPath }}</span>
|
|
6
|
+
</header>
|
|
7
|
+
<ValidationReport
|
|
8
|
+
v-if="report.type === 'validate'"
|
|
9
|
+
:report="report.data as SingleValidationReport"
|
|
10
|
+
/>
|
|
11
|
+
<LintReport v-else-if="report.type === 'lint'" :report="report.data as SingleLintReport" />
|
|
12
|
+
<CleanReport v-else-if="report.type === 'clean'" :report="report.data as SingleCleanReport" />
|
|
13
|
+
<RoundtripReport
|
|
14
|
+
v-else-if="report.type === 'roundtrip'"
|
|
15
|
+
:report="report.data as SingleRoundTripReport"
|
|
16
|
+
/>
|
|
17
|
+
<ExportReport
|
|
18
|
+
v-else-if="report.type === 'export' || report.type === 'convert'"
|
|
19
|
+
:result="report.data as ExportResult | ConvertResult"
|
|
20
|
+
/>
|
|
21
|
+
<TreeValidationReport
|
|
22
|
+
v-else-if="report.type === 'validate-tree'"
|
|
23
|
+
:report="report.data as TreeValidationReportData"
|
|
24
|
+
/>
|
|
25
|
+
<TreeLintReport
|
|
26
|
+
v-else-if="report.type === 'lint-tree'"
|
|
27
|
+
:report="report.data as LintTreeReportData"
|
|
28
|
+
/>
|
|
29
|
+
<TreeCleanReport
|
|
30
|
+
v-else-if="report.type === 'clean-tree'"
|
|
31
|
+
:report="report.data as TreeCleanReportData"
|
|
32
|
+
/>
|
|
33
|
+
<TreeRoundtripReport
|
|
34
|
+
v-else-if="report.type === 'roundtrip-tree'"
|
|
35
|
+
:report="report.data as RoundTripTreeReportData"
|
|
36
|
+
/>
|
|
37
|
+
<p v-else class="unknown-type">Unknown report type: {{ report.type }}</p>
|
|
38
|
+
</div>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<script setup lang="ts">
|
|
42
|
+
import { computed } from "vue";
|
|
43
|
+
import type {
|
|
44
|
+
SingleValidationReport,
|
|
45
|
+
SingleLintReport,
|
|
46
|
+
SingleCleanReport,
|
|
47
|
+
SingleRoundTripReport,
|
|
48
|
+
ExportResult,
|
|
49
|
+
ConvertResult,
|
|
50
|
+
TreeValidationReport as TreeValidationReportData,
|
|
51
|
+
LintTreeReport as LintTreeReportData,
|
|
52
|
+
TreeCleanReport as TreeCleanReportData,
|
|
53
|
+
RoundTripTreeReport as RoundTripTreeReportData,
|
|
54
|
+
} from "@galaxy-tool-util/schema";
|
|
55
|
+
import ValidationReport from "./ValidationReport.vue";
|
|
56
|
+
import LintReport from "./LintReport.vue";
|
|
57
|
+
import CleanReport from "./CleanReport.vue";
|
|
58
|
+
import RoundtripReport from "./RoundtripReport.vue";
|
|
59
|
+
import ExportReport from "./ExportReport.vue";
|
|
60
|
+
import TreeValidationReport from "./TreeValidationReport.vue";
|
|
61
|
+
import TreeLintReport from "./TreeLintReport.vue";
|
|
62
|
+
import TreeCleanReport from "./TreeCleanReport.vue";
|
|
63
|
+
import TreeRoundtripReport from "./TreeRoundtripReport.vue";
|
|
64
|
+
|
|
65
|
+
interface ReportPayload {
|
|
66
|
+
type:
|
|
67
|
+
| "validate"
|
|
68
|
+
| "lint"
|
|
69
|
+
| "clean"
|
|
70
|
+
| "roundtrip"
|
|
71
|
+
| "export"
|
|
72
|
+
| "convert"
|
|
73
|
+
| "validate-tree"
|
|
74
|
+
| "lint-tree"
|
|
75
|
+
| "clean-tree"
|
|
76
|
+
| "roundtrip-tree";
|
|
77
|
+
data: unknown;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const props = defineProps<{ report: ReportPayload }>();
|
|
81
|
+
|
|
82
|
+
const typeLabel = computed(() => {
|
|
83
|
+
const labels: Record<ReportPayload["type"], string> = {
|
|
84
|
+
validate: "Validate",
|
|
85
|
+
lint: "Lint",
|
|
86
|
+
clean: "Clean",
|
|
87
|
+
roundtrip: "Roundtrip",
|
|
88
|
+
export: "Export",
|
|
89
|
+
convert: "Convert",
|
|
90
|
+
"validate-tree": "Validate Tree",
|
|
91
|
+
"lint-tree": "Lint Tree",
|
|
92
|
+
"clean-tree": "Clean Tree",
|
|
93
|
+
"roundtrip-tree": "Roundtrip Tree",
|
|
94
|
+
};
|
|
95
|
+
return labels[props.report.type] ?? props.report.type;
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
const workflowPath = computed(() => {
|
|
99
|
+
const d = props.report.data as Record<string, unknown> | null;
|
|
100
|
+
if (typeof d?.workflow === "string") return d.workflow;
|
|
101
|
+
if (typeof d?.source_path === "string") return d.source_path;
|
|
102
|
+
if (typeof d?.root === "string") return d.root;
|
|
103
|
+
return null;
|
|
104
|
+
});
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<style scoped>
|
|
108
|
+
.gxwf-report-shell {
|
|
109
|
+
font-family:
|
|
110
|
+
system-ui,
|
|
111
|
+
-apple-system,
|
|
112
|
+
sans-serif;
|
|
113
|
+
padding: 1.5rem;
|
|
114
|
+
max-width: 1200px;
|
|
115
|
+
margin: 0 auto;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.report-header {
|
|
119
|
+
display: flex;
|
|
120
|
+
align-items: baseline;
|
|
121
|
+
gap: 0.75rem;
|
|
122
|
+
margin-bottom: 1.25rem;
|
|
123
|
+
padding-bottom: 0.75rem;
|
|
124
|
+
border-bottom: 1px solid var(--p-content-border-color, #dee2e6);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.report-type {
|
|
128
|
+
font-size: 1.25rem;
|
|
129
|
+
font-weight: 600;
|
|
130
|
+
text-transform: capitalize;
|
|
131
|
+
color: var(--p-text-color, #212529);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.report-path {
|
|
135
|
+
font-family: monospace;
|
|
136
|
+
font-size: 0.9rem;
|
|
137
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
138
|
+
overflow: hidden;
|
|
139
|
+
text-overflow: ellipsis;
|
|
140
|
+
white-space: nowrap;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
.unknown-type {
|
|
144
|
+
color: var(--p-text-color-secondary, #6c757d);
|
|
145
|
+
font-style: italic;
|
|
146
|
+
}
|
|
147
|
+
</style>
|