mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-10-28 02:58:18 +08:00
Vue rewrite of admin data manager (local data): view job page
* Rewrite (old mako, new json interface, new vue component) - View job page (view_job.mako, job_info, DataManagerJob) * Added Selenium test for DataManagerJob component (view job page)
This commit is contained in:
@@ -0,0 +1,160 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-breadcrumb :items="breadcrumbItems" />
|
||||
<Alert :message="message" :variant="status" />
|
||||
<Alert v-for="(error, index) in errorMessages" :key="index" :message="error" variant="error" />
|
||||
<Alert v-if="viewOnly" message="Not implemented" variant="dark" />
|
||||
<b-container v-else>
|
||||
<b-row>
|
||||
<b-col>
|
||||
<b-card header-bg-variant="primary" header-text-variant="white" border-variant="primary" class="mb-3" id="data-manager-card">
|
||||
<template slot="header">
|
||||
<b-container>
|
||||
<b-row align-v="center">
|
||||
<b-col cols="auto">
|
||||
<b-button v-b-tooltip.hover title="Rerun" :href="runUrl">
|
||||
<span class="fa fa-refresh" />
|
||||
</b-button>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b>{{ dataManager["name"] }}</b>
|
||||
<i>{{ dataManager['description'] }}</i>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</template>
|
||||
<b-card v-for="(item, i) in tableItems" :key="i" class="mb-4" id="data-card">
|
||||
<template slot="header">
|
||||
<b-table :fields="fields" :items="[item]" caption-top small stacked>
|
||||
<template slot="table-caption">
|
||||
<b-container>
|
||||
<b-row align-v="center">
|
||||
<b-col cols="auto">
|
||||
<b-button v-b-tooltip.hover title="View complete info" :href="tableItems[i]['infoUrl']" target="galaxy_main">
|
||||
<span class="fa fa-info-circle" />
|
||||
</b-button>
|
||||
</b-col>
|
||||
<b-col>
|
||||
<b>{{ item["name"] }}</b>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</template>
|
||||
</b-table>
|
||||
</template>
|
||||
<b-table v-for="(output, j) in dataManagerOutput[i]" :key="j" :fields="outputFields(output[1])" :items="output[1]" small stacked hover striped>
|
||||
<template slot="table-caption">
|
||||
Data Table:
|
||||
<b>{{ output[0] }}</b>
|
||||
</template>
|
||||
</b-table>
|
||||
</b-card>
|
||||
</b-card>
|
||||
</b-col>
|
||||
</b-row>
|
||||
</b-container>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
import Alert from "components/Alert.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Alert
|
||||
},
|
||||
props: {
|
||||
id: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
exitCode: Number,
|
||||
runUrl: "#",
|
||||
dataManager: [],
|
||||
hdaInfo: [],
|
||||
dataManagerOutput: [],
|
||||
errorMessages: [],
|
||||
fields: [
|
||||
{ key: "created" },
|
||||
{ key: "fileSize", label: "Filesize" },
|
||||
{
|
||||
key: "fileName",
|
||||
label: "Full path",
|
||||
tdClass: "table-cell-break-word"
|
||||
}
|
||||
],
|
||||
viewOnly: false,
|
||||
message: "",
|
||||
status: ""
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
breadcrumbItems() {
|
||||
return [
|
||||
{
|
||||
text: "Data Managers",
|
||||
to: "/"
|
||||
},
|
||||
{
|
||||
text: this.dataManager["name"] + " ( " + this.dataManager["description"] + " )",
|
||||
href: this.dataManager["toolUrl"],
|
||||
target: "_blank"
|
||||
},
|
||||
{
|
||||
text: "Jobs",
|
||||
to: {
|
||||
name: "DataManagerJobs",
|
||||
params: { id: this.dataManager["id"] }
|
||||
}
|
||||
},
|
||||
{
|
||||
text: "Job " + this.jobId,
|
||||
active: true
|
||||
}
|
||||
];
|
||||
},
|
||||
tableItems() {
|
||||
let tableItems = this.hdaInfo;
|
||||
return tableItems;
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
outputFields(output) {
|
||||
let outputFields = [];
|
||||
for (const k of Object.keys(output[0])) {
|
||||
outputFields.push({ key: k, label: k });
|
||||
}
|
||||
return outputFields;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
axios
|
||||
.get(`${Galaxy.root}data_manager/job_info?id=${this.id}`)
|
||||
.then(response => {
|
||||
this.jobId = response.data.jobId;
|
||||
this.exitCode = response.data.exitCode;
|
||||
this.runUrl = response.data.runUrl;
|
||||
this.dataManager = response.data.dataManager;
|
||||
this.hdaInfo = response.data.hdaInfo;
|
||||
this.dataManagerOutput = response.data.dataManagerOutput;
|
||||
this.errorMessages = response.data.errorMessages;
|
||||
this.viewOnly = response.data.viewOnly;
|
||||
this.message = response.data.message;
|
||||
this.status = response.data.status;
|
||||
})
|
||||
.catch(error => {
|
||||
console.error(error);
|
||||
});
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.table-cell-break-word {
|
||||
word-break: break-word;
|
||||
}
|
||||
</style>
|
||||
@@ -35,7 +35,7 @@
|
||||
<b-button v-b-tooltip.hover title="Rerun" :href="jobs[row.index]['runUrl']">
|
||||
<span class="fa fa-refresh" />
|
||||
</b-button>
|
||||
<b-button v-b-tooltip.hover title="View Info" :href="jobs[row.index]['infoUrl']" target="galaxy_main" :id="'job-' + jobs[row.index]['encId']">
|
||||
<b-button v-b-tooltip.hover title="View Info" :to="{name: 'DataManagerJob', params: { id: jobs[row.index]['encId'] }}" :id="'job-' + jobs[row.index]['encId']">
|
||||
<span class="fa fa-info-circle" />
|
||||
</b-button>
|
||||
<b-button v-if="!showCommandLine" @click.stop="row.toggleDetails()" :pressed.sync="row.detailsShowing">
|
||||
|
||||
@@ -3,6 +3,7 @@ import Vue from "vue";
|
||||
import VueRouter from "vue-router";
|
||||
import DataManager from "./DataManager.vue";
|
||||
import DataManagerJobs from "./DataManagerJobs.vue";
|
||||
import DataManagerJob from "./DataManagerJob.vue";
|
||||
|
||||
Vue.use(VueRouter);
|
||||
|
||||
@@ -19,6 +20,12 @@ export default new VueRouter({
|
||||
name: "DataManagerJobs",
|
||||
component: DataManagerJobs,
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: "/job/:id",
|
||||
name: "DataManagerJob",
|
||||
component: DataManagerJob,
|
||||
props: true
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
@@ -7,6 +7,7 @@ from six import string_types
|
||||
|
||||
import galaxy.queue_worker
|
||||
from galaxy import web
|
||||
from galaxy.util import nice_size, unicodify
|
||||
from galaxy.web.base.controller import BaseUIController
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
@@ -64,7 +65,6 @@ class DataManager(BaseUIController):
|
||||
'id': j.id,
|
||||
'encId': trans.security.encode_id(j.id),
|
||||
'runUrl': web.url_for(controller="tool_runner", action="rerun", job_id=trans.security.encode_id(j.id)),
|
||||
'infoUrl': web.url_for(controller="data_manager", action="view_job", id=trans.security.encode_id(j.id)),
|
||||
'user': j.history.user.email if j.history and j.history.user else "anonymous",
|
||||
'updateTime': j.update_time.isoformat(),
|
||||
'state': j.state,
|
||||
@@ -83,12 +83,13 @@ class DataManager(BaseUIController):
|
||||
'status': status}
|
||||
|
||||
@web.expose
|
||||
def view_job(self, trans, **kwd):
|
||||
@web.json
|
||||
def job_info(self, trans, **kwd):
|
||||
not_is_admin = not trans.user_is_admin()
|
||||
if not_is_admin and not trans.app.config.enable_data_manager_user_view:
|
||||
raise paste.httpexceptions.HTTPUnauthorized("This Galaxy instance is not configured to allow non-admins to view the data manager.")
|
||||
message = escape(kwd.get('message', ''))
|
||||
status = escape(kwd.get('status', 'info'))
|
||||
message = kwd.get('message', '')
|
||||
status = kwd.get('status', 'info')
|
||||
job_id = kwd.get('id', None)
|
||||
try:
|
||||
job_id = trans.security.decode_id(job_id)
|
||||
@@ -101,19 +102,45 @@ class DataManager(BaseUIController):
|
||||
data_manager_id = job.data_manager_association.data_manager_id
|
||||
data_manager = trans.app.data_managers.get_manager(data_manager_id)
|
||||
hdas = [assoc.dataset for assoc in job.get_output_datasets()]
|
||||
hda_info = []
|
||||
data_manager_output = []
|
||||
error_messages = []
|
||||
for hda in hdas:
|
||||
hda_info.append({'id': hda.id,
|
||||
'encId': trans.security.encode_id(hda.id),
|
||||
'name': hda.name,
|
||||
'created': unicodify(hda.create_time.strftime(trans.app.config.pretty_datetime_format)),
|
||||
'fileSize': nice_size(hda.dataset.file_size),
|
||||
'fileName': hda.file_name,
|
||||
'infoUrl': web.url_for(controller='dataset',
|
||||
action='show_params',
|
||||
dataset_id=trans.security.encode_id(hda.id))})
|
||||
try:
|
||||
data_manager_json = loads(open(hda.get_file_name()).read())
|
||||
except Exception as e:
|
||||
data_manager_json = {}
|
||||
error_messages.append(escape("Unable to obtain data_table info for hda (%s): %s" % (hda.id, e)))
|
||||
error_messages.append("Unable to obtain data_table info for hda (%s): %s" % (hda.id, e))
|
||||
values = []
|
||||
for key, value in data_manager_json.get('data_tables', {}).items():
|
||||
values.append((key, value))
|
||||
data_manager_output.append(values)
|
||||
return trans.fill_template("data_manager/view_job.mako", data_manager=data_manager, job=job, view_only=not_is_admin, hdas=hdas, data_manager_output=data_manager_output, message=message, status=status, error_messages=error_messages)
|
||||
return {'jobId': job_id,
|
||||
'exitCode': job.exit_code,
|
||||
'runUrl': web.url_for(controller="tool_runner",
|
||||
action="rerun",
|
||||
job_id=trans.security.encode_id(job.id)),
|
||||
'commandLine': job.command_line,
|
||||
'dataManager': {'id': data_manager_id,
|
||||
'name': data_manager.name,
|
||||
'description': data_manager.description.lower(),
|
||||
'toolUrl': web.url_for(controller='root',
|
||||
tool_id=data_manager.tool.id)},
|
||||
'hdaInfo': hda_info,
|
||||
'dataManagerOutput': data_manager_output,
|
||||
'errorMessages': error_messages,
|
||||
'viewOnly': not_is_admin,
|
||||
'message': message,
|
||||
'status': status}
|
||||
|
||||
@web.expose
|
||||
def manage_data_table(self, trans, **kwd):
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<% from galaxy.util import nice_size, unicodify %>
|
||||
|
||||
<%def name="title()">Data Manager: ${ data_manager.name | h } - ${ data_manager.description | h }</%def>
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
%if error_messages:
|
||||
%for error_message in error_messages:
|
||||
${ render_msg( error_message, 'error' ) }
|
||||
%endfor
|
||||
%endif
|
||||
|
||||
%if view_only:
|
||||
<p>Not implemented</p>
|
||||
%else:
|
||||
%for i, hda in enumerate( hdas ):
|
||||
<table class="tabletip">
|
||||
<thead>
|
||||
<tr><th colspan="2" style="font-size: 120%;">
|
||||
Data Manager: <a href="${ h.url_for( controller='root', tool_id=data_manager.tool.id ) }" target="_blank">${ data_manager.name | h }</a> - ${ data_manager.description | h } <a class="icon-btn" href="${ h.url_for( controller="tool_runner", action="rerun", job_id=trans.security.encode_id( job.id ) ) }" title="Rerun" data-placement="bottom"><span class="fa fa-refresh"></span></a>
|
||||
</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr><td>Name:</td><td>${hda.name | h}</td></tr>
|
||||
<tr><td>Created:</td><td>${unicodify(hda.create_time.strftime(trans.app.config.pretty_datetime_format)) | h}</td></tr>
|
||||
<tr><td>Filesize:</td><td>${nice_size(hda.dataset.file_size) | h}</td></tr>
|
||||
<tr><td>Tool Exit Code:</td><td>${job.exit_code | h}</td></tr>
|
||||
<tr><td>Full Path:</td><td>${hda.file_name | h}</td></tr>
|
||||
<tr><td>View complete info:</td><td><a href="${h.url_for( controller='dataset', action='show_params', dataset_id=trans.security.encode_id( hda.id ))}">${ hda.id | h }</a></td></tr>
|
||||
|
||||
</table>
|
||||
<br />
|
||||
|
||||
<% json_tables = data_manager_output[i]%>
|
||||
%for table_name, json_table in json_tables:
|
||||
<table class="tabletip">
|
||||
<thead>
|
||||
<tr><th colspan="2" style="font-size: 120%;">
|
||||
Data Table: <a href="${h.url_for( controller='data_manager', action='manage_data_table', table_name=table_name)}">${ table_name | h }</a>
|
||||
</th></tr>
|
||||
</thead>
|
||||
<% len_json_table = len( json_table ) %>
|
||||
%for j, table_row in enumerate( json_table ):
|
||||
<tbody>
|
||||
%if len_json_table > 1:
|
||||
<tr><td><strong>Entry #${j | h}</strong></td><td> </td></tr>
|
||||
%endif
|
||||
%for name, value in table_row.iteritems():
|
||||
<tr><td>${name | h}:</td><td>${value | h}</td></tr>
|
||||
%endfor
|
||||
%endfor
|
||||
</tbody>
|
||||
</table>
|
||||
<br />
|
||||
%endfor
|
||||
|
||||
%endfor
|
||||
|
||||
%endif
|
||||
@@ -308,6 +308,9 @@ admin:
|
||||
dm_jobs_button: '#${data_manager}-jobs'
|
||||
dm_jobs_breadcrumb: '#breadcrumb'
|
||||
dm_jobs_table: '#jobs-table'
|
||||
dm_job: '#job-${job_id}'
|
||||
dm_job_data_manager_card: '#data-manager-card'
|
||||
dm_job_data_card: '#data-card'
|
||||
users_grid: '#users-grid'
|
||||
users_grid_create_button: '.manage-table-actions .action-button'
|
||||
groups_grid_create_button: '.manage-table-actions .action-button'
|
||||
|
||||
@@ -91,3 +91,8 @@ class AdminAppTestCase(SeleniumTestCase):
|
||||
admin_component.dm_jobs_breadcrumb.wait_for_visible()
|
||||
admin_component.dm_jobs_table.wait_for_visible()
|
||||
self.screenshot("admin_data_manager_jobs")
|
||||
|
||||
admin_component.dm_job(job_id=job_id).wait_for_and_click()
|
||||
admin_component.dm_job_data_manager_card.wait_for_visible()
|
||||
admin_component.dm_job_data_card.wait_for_visible()
|
||||
self.screenshot("admin_data_manager_job")
|
||||
|
||||
Reference in New Issue
Block a user