mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-24 16:30:27 +08:00
Merge branch 'dev' into admin_error_log
This commit is contained in:
@@ -4,12 +4,12 @@
|
||||
|
||||
import addLogging from "utils/add-logging";
|
||||
import { GalaxyApp } from "./galaxy";
|
||||
// import { serverPath } from "utils/serverPath";
|
||||
import { serverPath } from "utils/serverPath";
|
||||
|
||||
export function setGalaxyInstance(factory, atTop = true) {
|
||||
// console.warn("setGalaxyInstance", serverPath());
|
||||
export function setGalaxyInstance(factory) {
|
||||
console.warn("setGalaxyInstance", serverPath());
|
||||
|
||||
let storage = getStorage(atTop);
|
||||
let storage = getStorage();
|
||||
let newInstance = factory(GalaxyApp);
|
||||
if (!(newInstance instanceof GalaxyApp)) {
|
||||
newInstance = new GalaxyApp(newInstance);
|
||||
@@ -19,7 +19,6 @@ export function setGalaxyInstance(factory, atTop = true) {
|
||||
}
|
||||
|
||||
// Debugging frame property
|
||||
|
||||
// storage._galaxyInstance = new Proxy(newInstance, {
|
||||
// get(galaxy, prop) {
|
||||
// if (prop == "frame") {
|
||||
@@ -46,17 +45,18 @@ export function setGalaxyInstance(factory, atTop = true) {
|
||||
return storage._galaxyInstance;
|
||||
}
|
||||
|
||||
export function getGalaxyInstance(atTop = true) {
|
||||
let storage = getStorage(atTop);
|
||||
export function getGalaxyInstance() {
|
||||
let storage = getStorage();
|
||||
return storage._galaxyInstance;
|
||||
}
|
||||
|
||||
export function galaxyIsInitialized(atTop = true) {
|
||||
let instance = getGalaxyInstance(atTop);
|
||||
export function galaxyIsInitialized() {
|
||||
let instance = getGalaxyInstance();
|
||||
return instance !== null;
|
||||
}
|
||||
|
||||
export function getStorage(atTop = true) {
|
||||
let storage = window !== window.top && atTop ? window.top : window;
|
||||
return storage;
|
||||
// Having a CORS issue in the toolshed iframe, store separate versions
|
||||
// of galaxy in each window for the short-term
|
||||
export function getStorage() {
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ import DataTypes from "components/admin/DataTypes.vue";
|
||||
import DataManagerView from "components/admin/DataManager/DataManagerView.vue";
|
||||
import DataManagerRouter from "components/admin/DataManager/DataManagerRouter.vue";
|
||||
import ErrorStack from "components/admin/ErrorStack.vue";
|
||||
import DisplayApplications from "components/admin/DisplayApplications.vue";
|
||||
import Vue from "vue";
|
||||
import { serverPath } from "utils/serverPath";
|
||||
|
||||
@@ -35,6 +36,7 @@ window.app = function app(options, bootstrapped) {
|
||||
"(/)admin(/)roles": "show_roles",
|
||||
"(/)admin(/)groups": "show_groups",
|
||||
"(/)admin(/)error_stack": "show_error_stack",
|
||||
"(/)admin(/)display_applications": "show_display_applications",
|
||||
"(/)admin(/)tool_versions": "show_tool_versions",
|
||||
"(/)admin(/)quotas": "show_quotas",
|
||||
"(/)admin(/)repositories": "show_repositories",
|
||||
@@ -113,12 +115,14 @@ window.app = function app(options, bootstrapped) {
|
||||
})
|
||||
);
|
||||
},
|
||||
|
||||
_display_vue_helper: function(component, props) {
|
||||
let instance = Vue.extend(component);
|
||||
let vm = document.createElement("div");
|
||||
this.page.display(vm);
|
||||
new instance(props).$mount(vm);
|
||||
},
|
||||
|
||||
show_data_tables: function() {
|
||||
this._display_vue_helper(DataTables);
|
||||
},
|
||||
@@ -131,6 +135,10 @@ window.app = function app(options, bootstrapped) {
|
||||
this._display_vue_helper(ErrorStack);
|
||||
},
|
||||
|
||||
show_display_applications: function() {
|
||||
this._display_vue_helper(DisplayApplications);
|
||||
},
|
||||
|
||||
show_data_manager: function(path) {
|
||||
let vueMount = document.createElement("div");
|
||||
this.page.display(vueMount);
|
||||
|
||||
@@ -80,3 +80,6 @@ export function multiHistory(options) {
|
||||
multipanel.render(0);
|
||||
});
|
||||
}
|
||||
|
||||
// Used in common.mako
|
||||
export { default as store } from "store";
|
||||
@@ -34,6 +34,7 @@ var AdminPanel = Backbone.View.extend({
|
||||
{
|
||||
title: _l("Display applications"),
|
||||
url: "admin/display_applications",
|
||||
target: "__use_router__",
|
||||
id: "admin-link-display-applications"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -9,147 +9,154 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
style: {
|
||||
type: String,
|
||||
default: "light"
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
export default {
|
||||
props: {
|
||||
style: {
|
||||
type: String,
|
||||
default: "light"
|
||||
},
|
||||
size: {
|
||||
type: Number,
|
||||
default: 100
|
||||
},
|
||||
center: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.galaxy-loader.galaxy-loader_center {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
.galaxy-loader.galaxy-loader_center {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.galaxy-loader {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.galaxy-loader_light {
|
||||
background-color: transparent;
|
||||
border: 2px solid #58585a;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.galaxy-loader_dark {
|
||||
background-color: #2c3143;
|
||||
border: 2px solid #2c3143;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.galaxy-loader_eu {
|
||||
background-color: transparent;
|
||||
border: 2px solid #063591;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.galaxy-loader > div {
|
||||
background-color: rgba(255, 0, 0, 0.3);
|
||||
display: block;
|
||||
height: 18px;
|
||||
position: absolute;
|
||||
border-radius: 2px;
|
||||
|
||||
-webkit-animation: galaxy-loader_animation 1.2s infinite ease-in-out;
|
||||
animation: galaxy-loader_animation 1.2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.galaxy-loader > .galaxy-loader_strip-1 {
|
||||
top: 16px;
|
||||
left: 13px;
|
||||
width: 59px;
|
||||
|
||||
-webkit-animation-delay: -1.2s;
|
||||
animation-delay: -1.2s;
|
||||
}
|
||||
|
||||
.galaxy-loader > .galaxy-loader_strip-2 {
|
||||
top: 39px;
|
||||
left: 13px;
|
||||
width: 44px;
|
||||
|
||||
-webkit-animation-delay: -1.1s;
|
||||
animation-delay: -1.1s;
|
||||
}
|
||||
|
||||
.galaxy-loader > .galaxy-loader_strip-3 {
|
||||
top: 61px;
|
||||
left: 25px;
|
||||
width: 59px;
|
||||
|
||||
-webkit-animation-delay: -1s;
|
||||
animation-delay: -1s;
|
||||
}
|
||||
|
||||
.galaxy-loader_light > .galaxy-loader_strip-1,
|
||||
.galaxy-loader_light > .galaxy-loader_strip-2 {
|
||||
background-color: #58585a;
|
||||
}
|
||||
|
||||
.galaxy-loader_light > .galaxy-loader_strip-3 {
|
||||
background: linear-gradient(to right, rgba(207, 188, 59, 1), rgba(207, 188, 59, 1) 20%, rgba(207, 188, 59, 0) 100%);
|
||||
}
|
||||
|
||||
.galaxy-loader_dark > .galaxy-loader_strip-1,
|
||||
.galaxy-loader_dark > .galaxy-loader_strip-2 {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.galaxy-loader_dark > .galaxy-loader_strip-3 {
|
||||
background: linear-gradient(to right, rgba(207, 188, 59, 1), rgba(207, 188, 59, 1) 20%, rgba(207, 188, 59, 0) 100%);
|
||||
}
|
||||
|
||||
.galaxy-loader_eu > .galaxy-loader_strip-1,
|
||||
.galaxy-loader_eu > .galaxy-loader_strip-2 {
|
||||
background-color: #063591;
|
||||
}
|
||||
|
||||
.galaxy-loader_eu > .galaxy-loader_strip-3 {
|
||||
background: linear-gradient(to right, rgba(207, 188, 59, 1), rgba(207, 188, 59, 1) 20%, rgba(207, 188, 59, 0) 100%);
|
||||
}
|
||||
|
||||
@-webkit-keyframes galaxy-loader_animation {
|
||||
0%,
|
||||
60%,
|
||||
100% {
|
||||
-webkit-transform: scaleX(1);
|
||||
}
|
||||
|
||||
.galaxy-loader {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
border-radius: 50px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
20% {
|
||||
-webkit-transform: scaleX(0.8);
|
||||
}
|
||||
|
||||
.galaxy-loader_light {
|
||||
background-color: transparent;
|
||||
border: 2px solid #58585a;
|
||||
box-sizing: border-box;
|
||||
40% {
|
||||
-webkit-transform: scaleX(1.2);
|
||||
}
|
||||
}
|
||||
|
||||
.galaxy-loader_dark {
|
||||
background-color: #2c3143;
|
||||
border: 2px solid #2c3143;
|
||||
box-sizing: border-box;
|
||||
@keyframes galaxy-loader_animation {
|
||||
0%,
|
||||
60%,
|
||||
100% {
|
||||
transform: scaleX(1);
|
||||
-webkit-transform: scaleX(1);
|
||||
}
|
||||
|
||||
.galaxy-loader_eu {
|
||||
background-color: transparent;
|
||||
border: 2px solid #063591;
|
||||
box-sizing: border-box;
|
||||
20% {
|
||||
transform: scaleX(0.8);
|
||||
-webkit-transform: scaleX(0.8);
|
||||
}
|
||||
|
||||
.galaxy-loader > div {
|
||||
background-color: rgba(255, 0, 0, 0.3);
|
||||
display: block;
|
||||
height: 18px;
|
||||
position: absolute;
|
||||
border-radius: 2px;
|
||||
|
||||
-webkit-animation: galaxy-loader_animation 1.2s infinite ease-in-out;
|
||||
animation: galaxy-loader_animation 1.2s infinite ease-in-out;
|
||||
}
|
||||
|
||||
.galaxy-loader > .galaxy-loader_strip-1 {
|
||||
top: 16px;
|
||||
left: 13px;
|
||||
width: 59px;
|
||||
|
||||
-webkit-animation-delay: -1.2s;
|
||||
animation-delay: -1.2s;
|
||||
}
|
||||
|
||||
.galaxy-loader > .galaxy-loader_strip-2 {
|
||||
top: 39px;
|
||||
left: 13px;
|
||||
width: 44px;
|
||||
|
||||
-webkit-animation-delay: -1.1s;
|
||||
animation-delay: -1.1s;
|
||||
}
|
||||
|
||||
.galaxy-loader > .galaxy-loader_strip-3 {
|
||||
top: 61px;
|
||||
left: 25px;
|
||||
width: 59px;
|
||||
|
||||
-webkit-animation-delay: -1.0s;
|
||||
animation-delay: -1.0s;
|
||||
}
|
||||
|
||||
.galaxy-loader_light > .galaxy-loader_strip-1, .galaxy-loader_light > .galaxy-loader_strip-2 {
|
||||
background-color: #58585a;
|
||||
}
|
||||
|
||||
.galaxy-loader_light > .galaxy-loader_strip-3 {
|
||||
background: linear-gradient(to right, rgba(207, 188, 59, 1), rgba(207, 188, 59, 1) 20%, rgba(207, 188, 59, 0) 100%);
|
||||
}
|
||||
|
||||
.galaxy-loader_dark > .galaxy-loader_strip-1, .galaxy-loader_dark > .galaxy-loader_strip-2 {
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
.galaxy-loader_dark > .galaxy-loader_strip-3 {
|
||||
background: linear-gradient(to right, rgba(207, 188, 59, 1), rgba(207, 188, 59, 1) 20%, rgba(207, 188, 59, 0) 100%);
|
||||
}
|
||||
|
||||
.galaxy-loader_eu > .galaxy-loader_strip-1, .galaxy-loader_eu > .galaxy-loader_strip-2 {
|
||||
background-color: #063591;
|
||||
}
|
||||
|
||||
.galaxy-loader_eu > .galaxy-loader_strip-3 {
|
||||
background: linear-gradient(to right, rgba(207, 188, 59, 1), rgba(207, 188, 59, 1) 20%, rgba(207, 188, 59, 0) 100%);
|
||||
}
|
||||
|
||||
@-webkit-keyframes galaxy-loader_animation {
|
||||
0%, 60%, 100% {
|
||||
-webkit-transform: scaleX(1)
|
||||
}
|
||||
20% {
|
||||
-webkit-transform: scaleX(0.8)
|
||||
}
|
||||
40% {
|
||||
-webkit-transform: scaleX(1.2)
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes galaxy-loader_animation {
|
||||
0%, 60%, 100% {
|
||||
transform: scaleX(1);
|
||||
-webkit-transform: scaleX(1);
|
||||
}
|
||||
20% {
|
||||
transform: scaleX(0.8);
|
||||
-webkit-transform: scaleX(0.8);
|
||||
}
|
||||
40% {
|
||||
transform: scaleX(1.2);
|
||||
-webkit-transform: scaleX(1.2);
|
||||
}
|
||||
40% {
|
||||
transform: scaleX(1.2);
|
||||
-webkit-transform: scaleX(1.2);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -5,3 +5,13 @@ export function getErrorStack() {
|
||||
let url = `${getAppRoot()}api/tools/error_stack`;
|
||||
return axios.get(url);
|
||||
}
|
||||
|
||||
export function getDisplayApplications() {
|
||||
let url = `${getAppRoot()}api/display_applications`;
|
||||
return axios.get(url);
|
||||
}
|
||||
|
||||
export function reloadDisplayApplications(ids) {
|
||||
let url = `${getAppRoot()}api/display_applications/reload`;
|
||||
return axios.post(url, { ids: ids });
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<template>
|
||||
<div>
|
||||
<b-alert :show="messageVisible" :variant="messageVariant">
|
||||
{{ messageText }}
|
||||
</b-alert>
|
||||
<b-alert :show="warningVisible" variant="warning">
|
||||
No display applications available.
|
||||
</b-alert>
|
||||
<div v-if="applicationsVisible" class="card-header">
|
||||
There are currently {{ applicationsLength }}
|
||||
<b-button size="sm" @click.prevent="reloadAll()" title="Reload all display applications" data-placement="bottom">
|
||||
<span class="fa fa-refresh"/>
|
||||
</b-button>
|
||||
display applications loaded.
|
||||
</div>
|
||||
<b-table id="display-applications-grid" v-if="applicationsVisible" striped :fields="applicationsAttributes" :items="applications">
|
||||
<template slot="reload" slot-scope="data">
|
||||
<b-button size="sm" title="Reload display application" data-placement="bottom" @click.prevent="reload(data.item.id, data.index)">
|
||||
<span class="fa fa-refresh"/>
|
||||
</b-button>
|
||||
</template>
|
||||
<template slot="links" slot-scope="data">
|
||||
<li v-for="link in data.item.links">{{ link.name }}</li>
|
||||
</template>
|
||||
</b-table>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
import { getDisplayApplications, reloadDisplayApplications } from "./AdminServices.js";
|
||||
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
applications: [],
|
||||
applicationsLoaded: false,
|
||||
applicationsAttributes: [
|
||||
{ key: "reload" },
|
||||
{ key: "name", sortable: true },
|
||||
{ key: "id", sortable: true },
|
||||
{ key: "version" },
|
||||
{ key: "links" }
|
||||
],
|
||||
messageText: null,
|
||||
messageVariant: null
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
applicationsIndex: function() {
|
||||
let result = {};
|
||||
for (let app of this.applications) {
|
||||
result[app.id] = app;
|
||||
}
|
||||
return result;
|
||||
},
|
||||
applicationsAll: function() {
|
||||
let result = [];
|
||||
for (let app of this.applications) {
|
||||
result.push(app.id);
|
||||
}
|
||||
return result;
|
||||
},
|
||||
applicationsVisible: function() {
|
||||
return this.applications.length > 0;
|
||||
},
|
||||
applicationsLength: function() {
|
||||
return this.applications.length;
|
||||
},
|
||||
messageVisible: function() {
|
||||
return this.messageText != null;
|
||||
},
|
||||
warningVisible: function() {
|
||||
return !this.applicationsVisible && this.applicationsLoaded;
|
||||
}
|
||||
},
|
||||
created() {
|
||||
getDisplayApplications()
|
||||
.then(response => {
|
||||
this.applications = response.data;
|
||||
this.applicationsLoaded = true;
|
||||
})
|
||||
.catch(e => {
|
||||
this._errorMessage(e);
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
reload: function(id) {
|
||||
this._reload([id]);
|
||||
},
|
||||
reloadAll: function() {
|
||||
let ids = [];
|
||||
for (let app of this.applications) {
|
||||
ids.push(app.id);
|
||||
}
|
||||
this._reload(ids);
|
||||
},
|
||||
_reload: function(ids) {
|
||||
this._highlightRows(this.applicationsAll, "default");
|
||||
reloadDisplayApplications(ids)
|
||||
.then(response => {
|
||||
this.messageVariant = "info";
|
||||
this.messageText = response.data.message;
|
||||
this._highlightRows(response.data.failed, "danger");
|
||||
this._highlightRows(response.data.reloaded, "success");
|
||||
})
|
||||
.catch(e => {
|
||||
this._errorMessage(e);
|
||||
});
|
||||
},
|
||||
_highlightRows: function(appList, status) {
|
||||
for (let appIndex of appList) {
|
||||
let app = this.applicationsIndex[appIndex];
|
||||
if (app) {
|
||||
app._rowVariant = status;
|
||||
}
|
||||
}
|
||||
},
|
||||
_errorMessage: function(e) {
|
||||
let message = e && e.response && e.response.data && e.response.data.err_msg;
|
||||
this.messageText = message || "Request failed for an unknown reason.";
|
||||
this.messageVariant = "danger";
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -203,23 +203,29 @@ var CenterPanel = Backbone.View.extend({
|
||||
this.setElement($(this.template()));
|
||||
this.$frame = this.$(".center-frame");
|
||||
this.$panel = this.$(".center-panel");
|
||||
this.$frame.on("load", _.bind(this._iframeChangeHandler, this));
|
||||
this.$frame.on("load", this._iframeChangeHandler.bind(this));
|
||||
},
|
||||
|
||||
/** Display iframe if its target url changes, hide center panel */
|
||||
_iframeChangeHandler: function(ev) {
|
||||
var iframe = ev.currentTarget;
|
||||
var location = iframe.contentWindow && iframe.contentWindow.location;
|
||||
if (location && location.host) {
|
||||
$(iframe).show();
|
||||
this.$panel.empty().hide();
|
||||
var Galaxy = getGalaxyInstance();
|
||||
Galaxy.trigger("center-frame:load", {
|
||||
fullpath: location.pathname + location.search + location.hash,
|
||||
pathname: location.pathname,
|
||||
search: location.search,
|
||||
hash: location.hash
|
||||
});
|
||||
var Galaxy = getGalaxyInstance();
|
||||
// Adding try/catch to manage a CORS error in toolshed. Accessing
|
||||
// location.host is a CORS no-no
|
||||
try {
|
||||
if (location && location.host) {
|
||||
$(iframe).show();
|
||||
this.$panel.empty().hide();
|
||||
Galaxy.trigger("center-frame:load", {
|
||||
fullpath: location.pathname + location.search + location.hash,
|
||||
pathname: location.pathname,
|
||||
search: location.search,
|
||||
hash: location.hash
|
||||
});
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn("_iframeChangeHandler error", ev, location, Galaxy);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import LIST_ITEM from "mvc/list/list-item";
|
||||
import DATASET_LI from "mvc/dataset/dataset-li";
|
||||
import _ from "underscore";
|
||||
import $ from "jquery";
|
||||
import { ListItemView, FoldoutListItemView } from "mvc/list/list-item";
|
||||
import { DatasetListItemView } from "mvc/dataset/dataset-li";
|
||||
import BASE_MVC from "mvc/base-mvc";
|
||||
import _l from "utils/localization";
|
||||
|
||||
//==============================================================================
|
||||
var FoldoutListItemView = LIST_ITEM.FoldoutListItemView;
|
||||
|
||||
var ListItemView = LIST_ITEM.ListItemView;
|
||||
/** @class Read only view for DatasetCollection.
|
||||
*/
|
||||
var DCListItemView = FoldoutListItemView.extend(
|
||||
@@ -189,9 +187,9 @@ DCEListItemView.prototype.templates = (() => {
|
||||
/** @class Read only view for a DatasetCollectionElement that is also an DatasetAssociation
|
||||
* (a dataset contained in a dataset collection).
|
||||
*/
|
||||
var DatasetDCEListItemView = DATASET_LI.DatasetListItemView.extend(
|
||||
var DatasetDCEListItemView = DatasetListItemView.extend(
|
||||
/** @lends DatasetDCEListItemView.prototype */ {
|
||||
className: `${DATASET_LI.DatasetListItemView.prototype.className} dataset-collection-element`,
|
||||
className: `${DatasetListItemView.prototype.className} dataset-collection-element`,
|
||||
|
||||
/** set up */
|
||||
initialize: function(attributes) {
|
||||
@@ -199,7 +197,7 @@ var DatasetDCEListItemView = DATASET_LI.DatasetListItemView.extend(
|
||||
this.logger = this.model.logger = attributes.logger;
|
||||
}
|
||||
this.log("DatasetDCEListItemView.initialize:", attributes);
|
||||
DATASET_LI.DatasetListItemView.prototype.initialize.call(this, attributes);
|
||||
DatasetListItemView.prototype.initialize.call(this, attributes);
|
||||
},
|
||||
|
||||
/** In this override, only get details if in the ready state.
|
||||
@@ -210,7 +208,7 @@ var DatasetDCEListItemView = DATASET_LI.DatasetListItemView.extend(
|
||||
if (view.model.inReadyState() && !view.model.hasDetails()) {
|
||||
return view.model.fetch({ silent: true });
|
||||
}
|
||||
return jQuery.when();
|
||||
return $.when();
|
||||
},
|
||||
|
||||
// ......................................................................... misc
|
||||
@@ -239,7 +237,7 @@ DatasetDCEListItemView.prototype.templates = (() => {
|
||||
"element"
|
||||
);
|
||||
|
||||
return _.extend({}, DATASET_LI.DatasetListItemView.prototype.templates, {
|
||||
return _.extend({}, DatasetListItemView.prototype.templates, {
|
||||
titleBar: titleBarTemplate
|
||||
});
|
||||
})();
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import _ from "underscore";
|
||||
import { getAppRoot } from "onload/loadConfig";
|
||||
import LIST_VIEW from "mvc/list/list-view";
|
||||
import DC_MODEL from "mvc/collection/collection-model";
|
||||
import DC_LI from "mvc/collection/collection-li";
|
||||
import BASE_MVC from "mvc/base-mvc";
|
||||
import _l from "utils/localization";
|
||||
|
||||
var logNamespace = "collections";
|
||||
@@ -56,7 +54,6 @@ var CollectionView = _super.extend(
|
||||
var panel = this;
|
||||
this.handleWarning($newRender);
|
||||
panel.log("_queueNewRender:", $newRender, speed);
|
||||
|
||||
// TODO: jquery@1.12 doesn't change display when the elem has display: flex
|
||||
// this causes display: block for those elems after the use of show/hide animations
|
||||
// animations are removed from this view for now until fixed
|
||||
|
||||
@@ -83,7 +83,7 @@ var DatasetListItemEdit = _super.extend(
|
||||
}
|
||||
|
||||
// disable if still uploading or new
|
||||
} else if (_.contains([STATES.UPLOAD, STATES.NEW], this.model.get("state"))) {
|
||||
} else if ([STATES.UPLOAD, STATES.NEW].includes(this.model.get("state"))) {
|
||||
editBtnData.disabled = true;
|
||||
editBtnData.title = _l("This dataset is not yet editable");
|
||||
}
|
||||
@@ -119,10 +119,13 @@ var DatasetListItemEdit = _super.extend(
|
||||
|
||||
var state = this.model.get("state");
|
||||
|
||||
if (!this.model.isDeletedOrPurged() && _.contains([STATES.OK, STATES.FAILED_METADATA], state)) {
|
||||
if (!this.model.isDeletedOrPurged()) {
|
||||
//Enable tagging+annotation regardless of job state (see issue #6330)
|
||||
this._renderTags($details);
|
||||
this._renderAnnotation($details);
|
||||
this._makeDbkeyEditLink($details);
|
||||
if ([STATES.OK, STATES.FAILED_METADATA].includes(state)) {
|
||||
this._makeDbkeyEditLink($details);
|
||||
}
|
||||
}
|
||||
|
||||
this._setUpBehaviors($details);
|
||||
|
||||
@@ -20,7 +20,7 @@ var _super = LIST_ITEM.ListItemView;
|
||||
/** @class Read only list view for either LDDAs, HDAs, or HDADCEs.
|
||||
* Roughly, any DatasetInstance (and not a raw Dataset).
|
||||
*/
|
||||
var DatasetListItemView = _super.extend(
|
||||
export var DatasetListItemView = _super.extend(
|
||||
/** @lends DatasetListItemView.prototype */ {
|
||||
_logNamespace: logNamespace,
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import _ from "underscore";
|
||||
import STATES from "mvc/dataset/states";
|
||||
import DC_LI from "mvc/collection/collection-li";
|
||||
import DC_VIEW from "mvc/collection/collection-view";
|
||||
import BASE_MVC from "mvc/base-mvc";
|
||||
import HISTORY_ITEM_LI from "mvc/history/history-item-li";
|
||||
import _l from "utils/localization";
|
||||
|
||||
@@ -17,7 +17,8 @@ var HDCAListItemView = _super.extend(
|
||||
_setUpListeners: function() {
|
||||
_super.prototype._setUpListeners.call(this);
|
||||
var renderListen = (model, options) => {
|
||||
this.render();
|
||||
// We want this to swap immediately without extra animations.
|
||||
this.render(0);
|
||||
};
|
||||
if (this.model.jobStatesSummary) {
|
||||
this.listenTo(this.model.jobStatesSummary, "change", renderListen);
|
||||
@@ -64,9 +65,7 @@ var HDCAListItemView = _super.extend(
|
||||
|
||||
stateDescription: function() {
|
||||
var collection = this.model;
|
||||
var elementCount = collection.get("element_count");
|
||||
var jobStateSource = collection.get("job_source_type");
|
||||
var collectionType = this.model.get("collection_type");
|
||||
var collectionTypeDescription = DC_VIEW.collectionTypeDescription(collection);
|
||||
var simpleDescription = DC_VIEW.collectionDescription(collection);
|
||||
var jobStatesSummary = collection.jobStatesSummary;
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import Utils from "utils/utils";
|
||||
|
||||
function _templateNametag(tag) {
|
||||
return `<span style="${Utils.generateTagStyle(tag.slice(5))}" class="badge badge-primary badge-tags">${_.escape(tag.slice(5))}</span>`;
|
||||
return `<span style="${Utils.generateTagStyle(tag.slice(5))}" class="badge badge-primary badge-tags">${_.escape(
|
||||
tag.slice(5)
|
||||
)}</span>`;
|
||||
}
|
||||
|
||||
function nametagTemplate(historyItem) {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import $ from "jquery";
|
||||
import Backbone from "backbone";
|
||||
import _ from "underscore";
|
||||
import BASE_MVC from "mvc/base-mvc";
|
||||
import _l from "utils/localization";
|
||||
|
||||
var logNamespace = "list";
|
||||
//==============================================================================
|
||||
@@ -142,7 +144,7 @@ var ExpandableView = Backbone.View.extend(BASE_MVC.LoggableMixin).extend({
|
||||
if (!this.model.hasDetails()) {
|
||||
return this.model.fetch();
|
||||
}
|
||||
return jQuery.when();
|
||||
return $.when();
|
||||
},
|
||||
|
||||
/** Inner fn called when expand (public) has fetched the details */
|
||||
@@ -182,7 +184,7 @@ var ExpandableView = Backbone.View.extend(BASE_MVC.LoggableMixin).extend({
|
||||
*
|
||||
* Designed as a base class for history panel contents - but usable elsewhere (I hope).
|
||||
*/
|
||||
var ListItemView = ExpandableView.extend(
|
||||
export var ListItemView = ExpandableView.extend(
|
||||
BASE_MVC.mixin(BASE_MVC.SelectableViewMixin, BASE_MVC.DraggableViewMixin, {
|
||||
tagName: "div",
|
||||
className: "list-item",
|
||||
@@ -380,7 +382,7 @@ ListItemView.prototype.templates = (() => {
|
||||
*
|
||||
* _renderDetails does the work of creating this.details: a sub-view that shows the nested list
|
||||
*/
|
||||
var FoldoutListItemView = ListItemView.extend({
|
||||
export var FoldoutListItemView = ListItemView.extend({
|
||||
/** If 'foldout': show the sub-panel inside the expanded item
|
||||
* If 'drilldown': only fire events and handle by pub-sub
|
||||
* (allow the panel containing this item to attach it, hide itself, etc.)
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
import $ from "jquery";
|
||||
import Backbone from "backbone";
|
||||
import _ from "underscore";
|
||||
import LIST_ITEM from "mvc/list/list-item";
|
||||
import LoadingIndicator from "ui/loading-indicator";
|
||||
import BASE_MVC from "mvc/base-mvc";
|
||||
|
||||
@@ -208,9 +208,9 @@ var View = Backbone.View.extend({
|
||||
${_.reduce(
|
||||
filteredTags.slice(0, 5),
|
||||
(memo, tag) => {
|
||||
return `${memo} <div style="${Utils.generateTagStyle(tag.slice(5))}" class="badge badge-primary badge-tags">${_.escape(
|
||||
tag
|
||||
)}</div>`;
|
||||
return `${memo} <div style="${Utils.generateTagStyle(
|
||||
tag.slice(5)
|
||||
)}" class="badge badge-primary badge-tags">${_.escape(tag)}</div>`;
|
||||
},
|
||||
""
|
||||
)}
|
||||
|
||||
@@ -358,7 +358,8 @@ export function setWindowTitle(title) {
|
||||
* @returns {integer}
|
||||
*/
|
||||
function hashFnv32a(str) {
|
||||
var i, l,
|
||||
var i,
|
||||
l,
|
||||
hval = 0x811c9dc5;
|
||||
|
||||
for (i = 0, l = str.length; i < l; i++) {
|
||||
@@ -380,10 +381,8 @@ function hashFnv32a(str) {
|
||||
* Assumes r, g, b are in the set [0, 1]
|
||||
*/
|
||||
function contrastingColor(r, g, b) {
|
||||
var o = ((r * 255 * 299) +
|
||||
(g * 255 * 587) +
|
||||
(b * 255 * 114)) / 1000;
|
||||
return (o > 125) ? 'black' : 'white';
|
||||
var o = (r * 255 * 299 + g * 255 * 587 + b * 255 * 114) / 1000;
|
||||
return o > 125 ? "black" : "white";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -397,26 +396,26 @@ function contrastingColor(r, g, b) {
|
||||
* @param {number} l The lightness
|
||||
* @return {Array} The RGB representation
|
||||
*/
|
||||
function hslToRgb(h, s, l){
|
||||
function hslToRgb(h, s, l) {
|
||||
var r, g, b;
|
||||
|
||||
if(s == 0){
|
||||
if (s == 0) {
|
||||
r = g = b = l; // achromatic
|
||||
}else{
|
||||
var hue2rgb = function hue2rgb(p, q, t){
|
||||
if(t < 0) t += 1;
|
||||
if(t > 1) t -= 1;
|
||||
if(t < 1/6) return p + (q - p) * 6 * t;
|
||||
if(t < 1/2) return q;
|
||||
if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
|
||||
} else {
|
||||
var hue2rgb = function hue2rgb(p, q, t) {
|
||||
if (t < 0) t += 1;
|
||||
if (t > 1) t -= 1;
|
||||
if (t < 1 / 6) return p + (q - p) * 6 * t;
|
||||
if (t < 1 / 2) return q;
|
||||
if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6;
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
||||
var p = 2 * l - q;
|
||||
r = hue2rgb(p, q, h + 1/3);
|
||||
r = hue2rgb(p, q, h + 1 / 3);
|
||||
g = hue2rgb(p, q, h);
|
||||
b = hue2rgb(p, q, h - 1/3);
|
||||
b = hue2rgb(p, q, h - 1 / 3);
|
||||
}
|
||||
|
||||
return [r, g, b];
|
||||
@@ -431,12 +430,11 @@ export function generateTagStyle(tag) {
|
||||
var brColor = `hsl(${hue}, 100%, ${lightness - 40}%)`;
|
||||
|
||||
var [r, g, b] = hslToRgb(hue, 1.0, lightness / 100);
|
||||
var fgColor = contrastingColor(r, g, b)
|
||||
var fgColor = contrastingColor(r, g, b);
|
||||
|
||||
return `background-color: ${bgColor}; color: ${fgColor}; border: 1px solid ${brColor}`
|
||||
return `background-color: ${bgColor}; color: ${fgColor}; border: 1px solid ${brColor}`;
|
||||
}
|
||||
|
||||
|
||||
export default {
|
||||
cssLoadFile: cssLoadFile,
|
||||
cssGetAttribute: cssGetAttribute,
|
||||
|
||||
@@ -538,6 +538,7 @@
|
||||
<datatype extension="biom2" type="galaxy.datatypes.binary:Biom2" mimetype="application/octet-stream" display_in_upload="true">
|
||||
<converter file="biom2_to_biom1.xml" target_datatype="biom1"/>
|
||||
</datatype>
|
||||
<datatype extension="msh" type="galaxy.datatypes.binary:MashSketch" display_in_upload="True" />
|
||||
<!-- Strand-specific Coordinate Count Datatype used by the Center for Eukaryotic Gene Regulation labs at Penn State -->
|
||||
<datatype extension="scidx" type="galaxy.datatypes.interval:ScIdx" display_in_upload="true"/>
|
||||
<!--Cheminformatics Datatypes -->
|
||||
|
||||
@@ -121,10 +121,6 @@
|
||||
<tool file="phenotype_association/linkToGProfile.xml" />
|
||||
<tool file="phenotype_association/linkToDavid.xml" />
|
||||
<tool file="phenotype_association/ldtools.xml" />
|
||||
<tool file="phenotype_association/pass.xml" />
|
||||
<tool file="phenotype_association/gpass.xml" />
|
||||
<tool file="phenotype_association/beam.xml" />
|
||||
<tool file="phenotype_association/lps.xml" />
|
||||
<tool file="phenotype_association/master2pg.xml" />
|
||||
</section>
|
||||
</toolbox>
|
||||
|
||||
@@ -120,7 +120,7 @@ B: Update the dictionary structure in kwargs.
|
||||
|
||||
::
|
||||
|
||||
kwargs['runner_param_specs'].update(runner_param_specs)
|
||||
kwargs.update({'runner_param_specs': runner_param_specs})
|
||||
|
||||
C: Now call the parent constructor to assign the values.
|
||||
|
||||
|
||||
@@ -126,6 +126,18 @@ class Cel(Binary):
|
||||
return False
|
||||
|
||||
|
||||
class MashSketch(Binary):
|
||||
"""
|
||||
Mash Sketch file.
|
||||
Sketches are used by the MinHash algorithm to allow fast distance estimations
|
||||
with low storage and memory requirements. To make a sketch, each k-mer in a sequence
|
||||
is hashed, which creates a pseudo-random identifier. By sorting these identifiers (hashes),
|
||||
a small subset from the top of the sorted list can represent the entire sequence (these are min-hashes).
|
||||
The more similar another sequence is, the more min-hashes it is likely to share.
|
||||
"""
|
||||
file_ext = "msh"
|
||||
|
||||
|
||||
class CompressedArchive(Binary):
|
||||
"""
|
||||
Class describing an compressed binary file
|
||||
|
||||
@@ -1441,11 +1441,9 @@ class JobWrapper(HasResourceParameters):
|
||||
# why not re-use self.param_dict here?
|
||||
param_dict = dict([(p.name, p.value) for p in job.parameters])
|
||||
param_dict = self.tool.params_from_strings(param_dict, self.app)
|
||||
# Create generated output children and primary datasets and add to param_dict
|
||||
# Create generated output children and primary datasets and dynamic outputs.
|
||||
tool_working_directory = self.tool_working_directory
|
||||
collected_datasets = {
|
||||
'primary': self.tool.collect_primary_datasets(out_data, self.get_tool_provided_job_metadata(), tool_working_directory, input_ext, input_dbkey)
|
||||
}
|
||||
self.tool.collect_primary_datasets(out_data, self.get_tool_provided_job_metadata(), tool_working_directory, input_ext, input_dbkey)
|
||||
self.tool.collect_dynamic_outputs(
|
||||
out_collections,
|
||||
self.get_tool_provided_job_metadata(),
|
||||
@@ -1454,7 +1452,6 @@ class JobWrapper(HasResourceParameters):
|
||||
job=job,
|
||||
input_dbkey=input_dbkey,
|
||||
)
|
||||
param_dict.update({'__collected_datasets__': collected_datasets})
|
||||
# Certain tools require tasks to be completed after job execution
|
||||
# ( this used to be performed in the "exec_after_process" hook, but hooks are deprecated ).
|
||||
self.tool.exec_after_process(self.app, inp_data, out_data, param_dict, job=job)
|
||||
|
||||
@@ -81,9 +81,11 @@
|
||||
|
||||
.. class:: infomark
|
||||
|
||||
This tool will take an input list and a text file with identifiers to
|
||||
filter the list with. It will build two new lists - one "filtered" to
|
||||
contain only the supplied identifiers and one of the discarded elements.
|
||||
This tool will take an input list and a text file with
|
||||
names (i.e. identifiers). It will split the input list into
|
||||
two new lists - one filtered to contain only the list members
|
||||
whose names are listed in the text file, and one containing
|
||||
all the other elements.
|
||||
|
||||
This tool will create new history datasets from your collection
|
||||
but your quota usage will not increase.
|
||||
|
||||
@@ -613,6 +613,7 @@ def collect_primary_datasets(tool, output, tool_provided_metadata, job_working_d
|
||||
extra_files_path_joined = os.path.join(job_working_directory, extra_files_path)
|
||||
for root, dirs, files in os.walk(extra_files_path_joined):
|
||||
extra_dir = os.path.join(primary_data.extra_files_path, root.replace(extra_files_path_joined, '', 1).lstrip(os.path.sep))
|
||||
extra_dir = os.path.normpath(extra_dir)
|
||||
for f in files:
|
||||
app.object_store.update_from_file(
|
||||
primary_data.dataset,
|
||||
@@ -620,7 +621,6 @@ def collect_primary_datasets(tool, output, tool_provided_metadata, job_working_d
|
||||
alt_name=f,
|
||||
file_name=os.path.join(root, f),
|
||||
create=True,
|
||||
dir_only=True,
|
||||
preserve_symlinks=True
|
||||
)
|
||||
metadata_dict = new_primary_datasets_attributes.get('metadata', None)
|
||||
@@ -631,8 +631,6 @@ def collect_primary_datasets(tool, output, tool_provided_metadata, job_working_d
|
||||
else:
|
||||
primary_data.set_meta()
|
||||
primary_data.set_peek()
|
||||
sa_session.add(primary_data)
|
||||
sa_session.flush()
|
||||
outdata.history.add_dataset(primary_data)
|
||||
# Add dataset to return dict
|
||||
primary_datasets[name][designation] = primary_data
|
||||
@@ -651,7 +649,8 @@ def collect_primary_datasets(tool, output, tool_provided_metadata, job_working_d
|
||||
outdata.set_meta()
|
||||
outdata.set_peek()
|
||||
sa_session.add(outdata)
|
||||
sa_session.flush()
|
||||
|
||||
sa_session.flush()
|
||||
return primary_datasets
|
||||
|
||||
|
||||
|
||||
@@ -69,6 +69,9 @@ def verify(
|
||||
errmsg += str(err)
|
||||
raise AssertionError(errmsg)
|
||||
|
||||
if attributes is None:
|
||||
attributes = {}
|
||||
|
||||
if filename is not None:
|
||||
local_name = get_filename(filename)
|
||||
temp_name = make_temp_fname(fname=filename)
|
||||
@@ -88,8 +91,6 @@ def verify(
|
||||
else:
|
||||
log.debug('## GALAXY_TEST_SAVE=%s. saved %s' % (keep_outputs_dir, ofn))
|
||||
try:
|
||||
if attributes is None:
|
||||
attributes = {}
|
||||
compare = attributes.get('compare', 'diff')
|
||||
if attributes.get('ftype', None) in ['bam', 'qname_sorted.bam', 'qname_input_sorted.bam', 'unsorted.bam']:
|
||||
local_fh, temp_name = _bam_to_sam(local_name, temp_name)
|
||||
@@ -110,10 +111,6 @@ def verify(
|
||||
files_contains(local_name, temp_name, attributes=attributes)
|
||||
else:
|
||||
raise Exception('Unimplemented Compare type: %s' % compare)
|
||||
if verify_extra_files:
|
||||
extra_files = attributes.get('extra_files', None)
|
||||
if extra_files:
|
||||
verify_extra_files(extra_files)
|
||||
except AssertionError as err:
|
||||
errmsg = '%s different than expected, difference (using %s):\n' % (item_label, compare)
|
||||
errmsg += "( %s v. %s )\n" % (local_name, temp_name)
|
||||
@@ -123,6 +120,11 @@ def verify(
|
||||
if 'GALAXY_TEST_NO_CLEANUP' not in os.environ:
|
||||
os.remove(temp_name)
|
||||
|
||||
if verify_extra_files:
|
||||
extra_files = attributes.get('extra_files', None)
|
||||
if extra_files:
|
||||
verify_extra_files(extra_files)
|
||||
|
||||
|
||||
def make_temp_fname(fname=None):
|
||||
"""Safe temp name - preserve the file extension for tools that interpret it."""
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
"""
|
||||
API operations on annotations.
|
||||
"""
|
||||
import logging
|
||||
|
||||
from galaxy import queue_worker
|
||||
from galaxy.web import expose_api, require_admin
|
||||
from galaxy.web.base.controller import BaseAPIController
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DisplayApplicationsController(BaseAPIController):
|
||||
|
||||
@expose_api
|
||||
def index(self, trans, **kwd):
|
||||
"""
|
||||
GET /api/display_applications/
|
||||
|
||||
Returns the list of display applications.
|
||||
|
||||
:returns: list of available display applications
|
||||
:rtype: list
|
||||
"""
|
||||
response = []
|
||||
for display_app in trans.app.datatypes_registry.display_applications.values():
|
||||
response.append({
|
||||
'id' : display_app.id,
|
||||
'name': display_app.name,
|
||||
'version': display_app.version,
|
||||
'filename_': display_app._filename,
|
||||
'links': [{'name': l.name} for l in display_app.links.values()]
|
||||
})
|
||||
return response
|
||||
|
||||
@expose_api
|
||||
@require_admin
|
||||
def reload(self, trans, payload={}, **kwd):
|
||||
"""
|
||||
POST /api/display_applications/reload
|
||||
|
||||
Reloads the list of display applications.
|
||||
|
||||
:param ids: list containing ids of display to be reloaded
|
||||
:type ids: list
|
||||
"""
|
||||
ids = payload.get('ids')
|
||||
queue_worker.send_control_task(trans.app,
|
||||
'reload_display_application',
|
||||
noop_self=True,
|
||||
kwargs={'display_application_ids': ids})
|
||||
reloaded, failed = trans.app.datatypes_registry.reload_display_applications(ids)
|
||||
if not reloaded and failed:
|
||||
message = 'Unable to reload any of the %i requested display applications ("%s").' % (len(failed), '", "'.join(failed))
|
||||
elif failed:
|
||||
message = 'Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").' % (len(reloaded), '", "'.join(reloaded), len(failed), '", "'.join(failed))
|
||||
elif not reloaded:
|
||||
message = 'You need to request at least one display application to reload.'
|
||||
else:
|
||||
message = 'Reloaded %i requested display applications ("%s").' % (len(reloaded), '", "'.join(reloaded))
|
||||
return {'message': message, 'reloaded': reloaded, 'failed': failed}
|
||||
@@ -104,6 +104,7 @@ def app_factory(global_conf, load_app_kwds={}, **kwargs):
|
||||
webapp.add_client_route('/admin/data_manager{path_info:.*}', 'admin')
|
||||
webapp.add_client_route('/admin/error_stack', 'admin')
|
||||
webapp.add_client_route('/admin/users', 'admin')
|
||||
webapp.add_client_route('/admin/display_applications', 'admin')
|
||||
webapp.add_client_route('/admin/roles', 'admin')
|
||||
webapp.add_client_route('/admin/forms', 'admin')
|
||||
webapp.add_client_route('/admin/groups', 'admin')
|
||||
@@ -555,6 +556,22 @@ def populate_api_routes(webapp, app):
|
||||
action='get_api_key',
|
||||
conditions=dict(method=["GET"]))
|
||||
|
||||
# ======================================
|
||||
# ====== DISPLAY APPLICATIONS API ======
|
||||
# ======================================
|
||||
|
||||
webapp.mapper.connect('index',
|
||||
'/api/display_applications',
|
||||
controller='display_applications',
|
||||
action='index',
|
||||
conditions=dict(method=["GET"]))
|
||||
|
||||
webapp.mapper.connect('reload',
|
||||
'/api/display_applications/reload',
|
||||
controller='display_applications',
|
||||
action='reload',
|
||||
conditions=dict(method=["POST"]))
|
||||
|
||||
# =====================
|
||||
# ===== TOURS API =====
|
||||
# =====================
|
||||
|
||||
@@ -902,29 +902,6 @@ class AdminGalaxy(controller.JSAppLauncher, AdminActions, UsesQuotaMixin, QuotaP
|
||||
message=message,
|
||||
status=status)
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def display_applications(self, trans, **kwd):
|
||||
return trans.fill_template('admin/view_display_applications.mako', display_applications=trans.app.datatypes_registry.display_applications)
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def reload_display_application(self, trans, **kwd):
|
||||
galaxy.queue_worker.send_control_task(trans.app,
|
||||
'reload_display_application',
|
||||
noop_self=True,
|
||||
kwargs={'display_application_ids': kwd.get('id')})
|
||||
reloaded, failed = trans.app.datatypes_registry.reload_display_applications(kwd.get('id'))
|
||||
if not reloaded and failed:
|
||||
return trans.show_error_message('Unable to reload any of the %i requested display applications ("%s").'
|
||||
% (len(failed), '", "'.join(failed)))
|
||||
if failed:
|
||||
return trans.show_warn_message('Reloaded %i display applications ("%s"), but failed to reload %i display applications ("%s").'
|
||||
% (len(reloaded), '", "'.join(reloaded), len(failed), '", "'.join(failed)))
|
||||
if not reloaded:
|
||||
return trans.show_warn_message('You need to request at least one display application to reload.')
|
||||
return trans.show_ok_message('Reloaded %i requested display applications ("%s").' % (len(reloaded), '", "'.join(reloaded)))
|
||||
|
||||
@web.expose
|
||||
@web.require_admin
|
||||
def center(self, trans, **kwd):
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<div class="card" id="display-applications-grid">
|
||||
<div class="card-header">There are currently ${len( display_applications )} <a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application' ) }" title="Reload all display applications" data-placement="bottom">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a> display applications loaded.</div>
|
||||
<div class="card-body overflow-auto">
|
||||
<table class="manage-table colored">
|
||||
<tr>
|
||||
<th>Reload</th>
|
||||
<th>Name</th>
|
||||
<th>ID</th>
|
||||
<th>Version</th>
|
||||
<th>Links</th>
|
||||
<th>Filename</th>
|
||||
</tr>
|
||||
<% ctr = 0 %>
|
||||
%for display_app in display_applications.values():
|
||||
%if ctr % 2 == 1:
|
||||
<tr class="odd_row">
|
||||
%else:
|
||||
<tr class="tr">
|
||||
%endif
|
||||
<td>
|
||||
<a class="icon-btn" href="${ h.url_for( controller='admin', action='reload_display_application', id=display_app.id ) }" title="Reload ${ display_app.name | h } display application" data-placement="bottom">
|
||||
<span class="fa fa-refresh"></span>
|
||||
</a>
|
||||
</td>
|
||||
<td>${ display_app.name | h }</td>
|
||||
<td>${ display_app.id | h }</td>
|
||||
<td>${ display_app.version | h }</td>
|
||||
<td><ul>
|
||||
%for link in display_app.links.values():
|
||||
<li>${ link.name | h }</li>
|
||||
%endfor
|
||||
</ul></td>
|
||||
<td>${ display_app._filename | h }</td>
|
||||
</tr>
|
||||
<% ctr += 1 %>
|
||||
%endfor
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
@@ -28,6 +28,9 @@
|
||||
<tool file="tool_provided_metadata_7.xml" />
|
||||
<tool file="tool_provided_metadata_8.xml" />
|
||||
<tool file="tool_provided_metadata_9.xml" />
|
||||
<tool file="tool_provided_metadata_10.xml" />
|
||||
<tool file="tool_provided_metadata_11.xml" />
|
||||
<tool file="tool_provided_metadata_12.xml" />
|
||||
<tool file="empty_datasets.xml" />
|
||||
<tool file="inputs_as_json.xml" />
|
||||
<tool file="inputs_as_json_with_paths.xml" />
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
<tool id="tool_provided_metadata_10" name="tool_provided_metadata_10" profile="17.09" version="1.0.0">
|
||||
<!-- Demonstrate setting datatype defined metadata for discovered datasets via galaxy.json for
|
||||
profile >= 17.09 tools (see tool_provided_metadata_3 for legacy version of this test). -->
|
||||
<command>
|
||||
echo "1" > sample1.report.tsv;
|
||||
cp $c1 galaxy.json;
|
||||
</command>
|
||||
<configfiles>
|
||||
<configfile name="c1">{"sample": {
|
||||
"datasets": [
|
||||
{"filename": "sample1.report.tsv", "name": "cool name 1", "ext": "txt", "info": "cool 1 info", "dbkey": "hg19", "metadata": {"data_lines": 10}}
|
||||
]
|
||||
}}
|
||||
</configfile>
|
||||
</configfiles>
|
||||
<inputs>
|
||||
<param name="input" type="data" />
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="sample">
|
||||
<discover_datasets pattern="(?P<designation>.+)\.report\.tsv" visible="true" />
|
||||
</data>
|
||||
</outputs>
|
||||
<tests>
|
||||
<test>
|
||||
<param name="input" ftype="txt" value="simple_line.txt"/>
|
||||
<output name="sample">
|
||||
<discovered_dataset designation="sample1" ftype="txt">
|
||||
<assert_contents><has_line line="1" /></assert_contents>
|
||||
<metadata name="name" value="cool name 1" />
|
||||
<metadata name="dbkey" value="hg19" />
|
||||
<metadata name="info" value="cool 1 info" />
|
||||
<metadata name="data_lines" value="10" />
|
||||
</discovered_dataset>
|
||||
</output>
|
||||
</test>
|
||||
</tests>
|
||||
</tool>
|
||||
@@ -0,0 +1,41 @@
|
||||
<tool id="tool_provided_metadata_11" name="tool_provided_metadata_11">
|
||||
<!-- Demonstrate setting simple dataset metadata for discovered datasets via galaxy.json for legacy tools (galaxy.json structure changes for profile >= 17.09 tools). -->
|
||||
<command>
|
||||
mkdir sample1data;
|
||||
echo "1" > sample1.report.tsv;
|
||||
echo "foo line" > sample1data/foo;
|
||||
echo "moo cow bar" > sample1data/bar;
|
||||
cp $c1 galaxy.json;
|
||||
</command>
|
||||
<configfiles>
|
||||
<configfile name="c1">{"type": "new_primary_dataset", "filename": "sample1.report.tsv", "name": "cool name 1", "ext": "txt", "info": "cool 1 info", "dbkey": "hg19", "extra_files": "sample1data"}
|
||||
</configfile>
|
||||
</configfiles>
|
||||
<inputs>
|
||||
<param name="input" type="data" />
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="sample">
|
||||
<discover_datasets pattern="(?P<designation>.+)\.report\.tsv" visible="true" />
|
||||
</data>
|
||||
</outputs>
|
||||
<tests>
|
||||
<test>
|
||||
<param name="input" ftype="txt" value="simple_line.txt"/>
|
||||
<output name="sample">
|
||||
<discovered_dataset designation="sample1" ftype="txt">
|
||||
<assert_contents><has_line line="1" /></assert_contents>
|
||||
<metadata name="name" value="cool name 1" />
|
||||
<metadata name="dbkey" value="hg19" />
|
||||
<metadata name="info" value="cool 1 info" />
|
||||
<extra_files type="file" name="foo">
|
||||
<assert_contents><has_line line="foo line" /></assert_contents>
|
||||
</extra_files>
|
||||
<extra_files type="file" name="bar">
|
||||
<assert_contents><has_line line="moo cow bar" /></assert_contents>
|
||||
</extra_files>
|
||||
</discovered_dataset>
|
||||
</output>
|
||||
</test>
|
||||
</tests>
|
||||
</tool>
|
||||
@@ -0,0 +1,45 @@
|
||||
<tool id="tool_provided_metadata_12" name="tool_provided_metadata_12" profile="17.09" version="1.0.0">
|
||||
<!-- Demonstrate setting extra_files for discovered primary datasets in profile >= 17.09 tools. -->
|
||||
<command>
|
||||
mkdir sample1data;
|
||||
echo "1" > sample1.report.tsv;
|
||||
echo "foo line" > sample1data/foo;
|
||||
echo "moo cow bar" > sample1data/bar;
|
||||
cp $c1 galaxy.json;
|
||||
</command>
|
||||
<configfiles>
|
||||
<configfile name="c1">{"sample": {
|
||||
"datasets": [
|
||||
{"filename": "sample1.report.tsv", "name": "cool name 1", "ext": "txt", "info": "cool 1 info", "dbkey": "hg19", "extra_files": "sample1data"}
|
||||
]
|
||||
}}
|
||||
</configfile>
|
||||
</configfiles>
|
||||
<inputs>
|
||||
<param name="input" type="data" />
|
||||
</inputs>
|
||||
<outputs>
|
||||
<data name="sample">
|
||||
<discover_datasets pattern="(?P<designation>.+)\.report\.tsv" visible="true" />
|
||||
</data>
|
||||
</outputs>
|
||||
<tests>
|
||||
<test>
|
||||
<param name="input" ftype="txt" value="simple_line.txt"/>
|
||||
<output name="sample">
|
||||
<discovered_dataset designation="sample1" ftype="txt">
|
||||
<assert_contents><has_line line="1" /></assert_contents>
|
||||
<metadata name="name" value="cool name 1" />
|
||||
<metadata name="dbkey" value="hg19" />
|
||||
<metadata name="info" value="cool 1 info" />
|
||||
<extra_files type="file" name="foo">
|
||||
<assert_contents><has_line line="foo line" /></assert_contents>
|
||||
</extra_files>
|
||||
<extra_files type="file" name="bar">
|
||||
<assert_contents><has_line line="moo cow bar" /></assert_contents>
|
||||
</extra_files>
|
||||
</discovered_dataset>
|
||||
</output>
|
||||
</test>
|
||||
</tests>
|
||||
</tool>
|
||||
@@ -23,8 +23,7 @@ class AdminAppTestCase(SeleniumTestCase):
|
||||
self.screenshot("admin_data_tables")
|
||||
|
||||
admin_component.index.display_applications.wait_for_and_click()
|
||||
with self.main_panel():
|
||||
admin_component.display_applications_grid.wait_for_visible()
|
||||
self.assert_warning_message("No display applications available.")
|
||||
self.screenshot("admin_display_applications")
|
||||
|
||||
admin_component.index.jobs.wait_for_and_click()
|
||||
|
||||
Reference in New Issue
Block a user