Remove unused modules, clear directories

This commit is contained in:
guerler
2022-09-22 01:42:40 -04:00
parent ab2ac4251b
commit d08196a170
41 changed files with 39 additions and 2483 deletions
+2 -2
View File
@@ -1,8 +1,8 @@
import $ from "jquery";
import _ from "underscore";
import Backbone from "backbone";
import BASE_MVC from "mvc/base-mvc";
import userModel from "mvc/user/user-model";
import BASE_MVC from "./base-mvc";
import userModel from "./user-model";
import metricsLogger from "utils/metrics-logger";
import addLogging from "utils/add-logging";
import localize from "utils/localization";
@@ -1,6 +1,6 @@
import Backbone from "backbone";
import { getAppRoot } from "onload/loadConfig";
import baseMVC from "mvc/base-mvc";
import baseMVC from "./base-mvc";
import _l from "utils/localization";
var logNamespace = "user";
+1 -1
View File
@@ -2,7 +2,7 @@
<div id="webhook-view" ref="webhook" />
</template>
<script>
import Webhooks from "mvc/webhooks";
import Webhooks from "utils/webhooks";
export default {
props: {
+1 -1
View File
@@ -1,4 +1,4 @@
import Webhooks from "mvc/webhooks";
import Webhooks from "utils/webhooks";
import Utils from "utils/utils";
export function loadWebhookMenuItems(items) {
@@ -8,7 +8,7 @@
<script>
import _l from "utils/localization";
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "./rule-definitions";
const MAPPING_TARGETS = RuleDefs.MAPPING_TARGETS;
export default {
@@ -16,7 +16,7 @@
<script>
import _l from "utils/localization";
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "./rule-definitions";
const RULES = RuleDefs.RULES;
export default {
@@ -9,7 +9,7 @@
</template>
<script>
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "./rule-definitions";
const RULES = RuleDefs.RULES;
export default {
@@ -26,7 +26,7 @@
import Vue from "vue";
import _l from "utils/localization";
import BootstrapVue from "bootstrap-vue";
import { RULES, MAPPING_TARGETS } from "mvc/rules/rule-definitions";
import { RULES, MAPPING_TARGETS } from "./rule-definitions";
import UtcDate from "components/UtcDate";
Vue.use(BootstrapVue);
@@ -575,10 +575,10 @@ import { refreshContentsWrapper } from "utils/data";
import HotTable from "@handsontable/vue";
import UploadUtils from "mvc/upload/upload-utils";
import JobStatesModel from "utils/job-states-model";
import RuleDefs from "mvc/rules/rule-definitions";
import Vue from "vue";
import BootstrapVue from "bootstrap-vue";
import Select2 from "components/Select2";
import RuleDefs from "components/RuleBuilder/rule-definitions";
import ColumnSelector from "components/RuleBuilder/ColumnSelector";
import RegularExpressionInput from "components/RuleBuilder/RegularExpressionInput";
import RuleDisplay from "components/RuleBuilder/RuleDisplay";
@@ -3,7 +3,7 @@
</template>
<script>
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "components/RuleBuilder/rule-definitions";
export default {
props: {
@@ -11,7 +11,7 @@
</template>
<script>
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "components/RuleBuilder/rule-definitions";
export default {
props: {
rule: {
@@ -17,7 +17,7 @@
</div>
</template>
<script>
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "components/RuleBuilder/rule-definitions";
import RuleDisplayPreview from "./RuleDisplayPreview";
import IdentifierDisplayPreview from "./IdentifierDisplayPreview";
+1 -1
View File
@@ -112,7 +112,7 @@ import FormMessage from "components/Form/FormMessage";
import ToolFooter from "components/Tool/ToolFooter";
import ToolHelp from "components/Tool/ToolHelp";
import ToolSourceMenuItem from "components/Tool/ToolSourceMenuItem";
import Webhooks from "mvc/webhooks";
import Webhooks from "utils/webhooks";
import { addFavorite, removeFavorite } from "components/Tool/services";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
import { library } from "@fortawesome/fontawesome-svg-core";
@@ -7,7 +7,7 @@ import UploadModel from "mvc/upload/upload-model";
import UploadWrapper from "./UploadWrapper";
import { defaultNewFileName, uploadModelsToPayload } from "./helpers";
import UploadFtp from "mvc/upload/upload-ftp";
import LazyLimited from "mvc/lazy/lazy-limited";
import LazyLimited from "./lazy-limited";
import { findExtension } from "./utils";
import { filesDialog, refreshContentsWrapper } from "utils/data";
import { getAppRoot } from "onload";
@@ -27,7 +27,7 @@
<script>
import { mapGetters } from "vuex";
import { WorkflowInvocationState } from "components/WorkflowInvocationState";
import Webhooks from "mvc/webhooks";
import Webhooks from "utils/webhooks";
import { getAppRoot } from "onload/loadConfig";
import { refreshContentsWrapper } from "utils/data";
-502
View File
@@ -1,502 +0,0 @@
import $ from "jquery";
import Backbone from "backbone";
import _ from "underscore";
import BASE_MVC from "mvc/base-mvc";
var logNamespace = "list";
//==============================================================================
/** A view which, when first rendered, shows only summary data/attributes, but
* can be expanded to show further details (and optionally fetch those
* details from the server).
*/
var ExpandableView = Backbone.View.extend(BASE_MVC.LoggableMixin).extend({
_logNamespace: logNamespace,
//TODO: Although the reasoning behind them is different, this shares a lot with HiddenUntilActivated above: combine them
//PRECONDITION: model must have method hasDetails
//PRECONDITION: subclasses must have templates.el and templates.details
initialize: function (attributes) {
/** are the details of this view expanded/shown or not? */
this.expanded = attributes.expanded || false;
this.log("\t expanded:", this.expanded);
this.fxSpeed = attributes.fxSpeed !== undefined ? attributes.fxSpeed : this.fxSpeed;
},
// ........................................................................ render main
/** jq fx speed */
fxSpeed: "fast",
/** Render this content, set up ui.
* @param {Number or String} speed the speed of the render
*/
render: function (speed) {
var $newRender = this._buildNewRender();
this._setUpBehaviors($newRender);
this._queueNewRender($newRender, speed);
return this;
},
/** Build a temp div containing the new children for the view's $el.
* If the view is already expanded, build the details as well.
*/
_buildNewRender: function () {
// create a new render using a skeleton template, render title buttons, render body, and set up events, etc.
var $newRender = $(this.templates.el(this.model.toJSON(), this));
if (this.expanded) {
this.$details($newRender).replaceWith(this._renderDetails().show());
}
return $newRender;
},
/** Fade out the old el, swap in the new contents, then fade in.
* @param {Number or String} speed jq speed to use for rendering effects
* @fires rendered when rendered
*/
_queueNewRender: function ($newRender, speed) {
speed = speed === undefined ? this.fxSpeed : speed;
var view = this;
if (speed === 0) {
view._swapNewRender($newRender);
view.trigger("rendered", view);
} else {
$(view).queue("fx", [
(next) => {
view.$el.fadeOut(speed, next);
},
(next) => {
view._swapNewRender($newRender);
next();
},
(next) => {
view.$el.fadeIn(speed, next);
},
(next) => {
view.trigger("rendered", view);
next();
},
]);
}
},
/** empty out the current el, move the $newRender's children in */
_swapNewRender: function ($newRender) {
return this.$el
.empty()
.attr("class", _.isFunction(this.className) ? this.className() : this.className)
.append($newRender.children());
},
/** set up js behaviors, event handlers for elements within the given container
* @param {jQuery} $container jq object that contains the elements to process (defaults to this.$el)
*/
_setUpBehaviors: function ($where) {
$where = $where || this.$el;
// set up canned behavior on children (bootstrap, popupmenus, editable_text, etc.)
//make_popup_menus( $where );
$where.find("[title]").tooltip({ placement: "bottom" });
},
// ......................................................................... details
/** shortcut to details DOM (as jQ) */
$details: function ($where) {
$where = $where || this.$el;
return $where.find("> .details");
},
/** build the DOM for the details and set up behaviors on it */
_renderDetails: function () {
var $newDetails = $(this.templates.details(this.model.toJSON(), this));
this._setUpBehaviors($newDetails);
return $newDetails;
},
// ......................................................................... expansion/details
/** Show or hide the details
* @param {Boolean} expand if true, expand; if false, collapse
*/
toggleExpanded: function (expand) {
expand = expand === undefined ? !this.expanded : expand;
if (expand) {
this.expand();
} else {
this.collapse();
}
return this;
},
/** Render and show the full, detailed body of this view including extra data and controls.
* note: if the model does not have detailed data, fetch that data before showing the body
* @fires expanded when a body has been expanded
*/
expand: function () {
var view = this;
return view._fetchModelDetails().always(() => {
view._expand();
});
},
/** Check for model details and, if none, fetch them.
* @returns {jQuery.promise} the model.fetch.xhr if details are being fetched, an empty promise if not
*/
_fetchModelDetails: function () {
if (!this.model.hasDetails()) {
return this.model.fetch();
}
return $.when();
},
/** Inner fn called when expand (public) has fetched the details */
_expand: function () {
var view = this;
var $newDetails = view._renderDetails();
view.$details().replaceWith($newDetails);
// needs to be set after the above or the slide will not show
view.expanded = true;
view.$details().slideDown(view.fxSpeed, () => {
view.trigger("expanded", view);
});
},
/** Hide the body/details of an HDA.
* @fires collapsed when a body has been collapsed
*/
collapse: function () {
this.debug(`${this}(ExpandableView).collapse`);
var view = this;
view.expanded = false;
this.$details().slideUp(view.fxSpeed, () => {
view.trigger("collapsed", view);
});
},
});
//==============================================================================
/** A view that is displayed in some larger list/grid/collection.
* Inherits from Expandable, Selectable, Draggable.
* The DOM contains warnings, a title bar, and a series of primary action controls.
* Primary actions are meant to be easily accessible item functions (such as delete)
* that are rendered in the title bar.
*
* Details are rendered when the user clicks the title bar or presses enter/space when
* the title bar is in focus.
*
* Designed as a base class for history panel contents - but usable elsewhere (I hope).
*/
export var ListItemView = ExpandableView.extend(
BASE_MVC.mixin(BASE_MVC.SelectableViewMixin, BASE_MVC.DraggableViewMixin, {
tagName: "div",
className: "list-item",
/** Set up the base class and all mixins */
initialize: function (attributes) {
ExpandableView.prototype.initialize.call(this, attributes);
BASE_MVC.SelectableViewMixin.initialize.call(this, attributes);
BASE_MVC.DraggableViewMixin.initialize.call(this, attributes);
this._setUpListeners();
},
/** event listeners */
_setUpListeners: function () {
// hide the primary actions in the title bar when selectable and narrow
this.on(
"selectable",
function (isSelectable) {
if (isSelectable) {
this.$(".primary-actions").hide();
} else {
this.$(".primary-actions").show();
}
},
this
);
return this;
},
// ........................................................................ rendering
/** In this override, call methods to build warnings, titlebar and primary actions */
_buildNewRender: function () {
var $newRender = ExpandableView.prototype._buildNewRender.call(this);
$newRender.children(".warnings").replaceWith(this._renderWarnings());
$newRender.children(".title-bar").replaceWith(this._renderTitleBar());
$newRender.children(".primary-actions").append(this._renderPrimaryActions());
$newRender.find("> .title-bar .subtitle").replaceWith(this._renderSubtitle());
return $newRender;
},
/** In this override, render the selector controls and set up dragging before the swap */
_swapNewRender: function ($newRender) {
ExpandableView.prototype._swapNewRender.call(this, $newRender);
if (this.selectable) {
this.showSelector(0);
}
if (this.draggable) {
this.draggableOn();
}
return this.$el;
},
/** Render any warnings the item may need to show (e.g. "I'm deleted") */
_renderWarnings: function () {
var view = this;
var $warnings = $('<div class="warnings"></div>');
var json = view.model.toJSON();
//TODO:! unordered (map)
_.each(view.templates.warnings, (templateFn) => {
$warnings.append($(templateFn(json, view)));
});
return $warnings;
},
/** Render the title bar (the main/exposed SUMMARY dom element) */
_renderTitleBar: function () {
return $(this.templates.titleBar(this.model.toJSON(), this));
},
/** Return an array of jQ objects containing common/easily-accessible item controls */
_renderPrimaryActions: function () {
// override this
return [];
},
/** Render the title bar (the main/exposed SUMMARY dom element) */
_renderSubtitle: function () {
return $(this.templates.subtitle(this.model.toJSON(), this));
},
// ......................................................................... events
/** event map */
events: {
// expand the body when the title is clicked or when in focus and space or enter is pressed
"click .title-bar": "_clickTitleBar",
"keydown .title-bar": "_keyDownTitleBar",
"click .selector": "toggleSelect",
},
/** expand when the title bar is clicked */
_clickTitleBar: function (event) {
event.stopPropagation();
if (event.altKey) {
this.toggleSelect(event);
if (!this.selectable) {
this.showSelector();
}
} else {
this.toggleExpanded();
}
},
/** expand when the title bar is in focus and enter or space is pressed */
_keyDownTitleBar: function (event) {
// bail (with propagation) if keydown and not space or enter
var KEYCODE_SPACE = 32;
var KEYCODE_RETURN = 13;
if (
event &&
event.type === "keydown" &&
(event.keyCode === KEYCODE_SPACE || event.keyCode === KEYCODE_RETURN)
) {
this.toggleExpanded();
event.stopPropagation();
return false;
}
return true;
},
// ......................................................................... misc
/** String representation */
toString: function () {
var modelString = this.model ? `${this.model}` : "(no model)";
return `ListItemView(${modelString})`;
},
})
);
// ............................................................................ TEMPLATES
/** underscore templates */
ListItemView.prototype.templates = (() => {
var elTemplato = BASE_MVC.wrapTemplate([
'<div class="list-element">',
// errors, messages, etc.
'<div class="warnings"></div>',
// multi-select checkbox
'<div class="selector">',
'<span class="fa fa-2x fa-square-o"></span>',
"</div>",
// space for title bar buttons - gen. floated to the right
'<div class="primary-actions"></div>',
'<div class="title-bar"></div>',
// expandable area for more details
'<div class="details"></div>',
"</div>",
]);
var warnings = {};
var titleBarTemplate = BASE_MVC.wrapTemplate(
[
// adding a tabindex here allows focusing the title bar and the use of keydown to expand the dataset display
'<div class="title-bar clear" tabindex="0">',
//TODO: prob. belongs in dataset-list-item
'<span class="state-icon"></span>',
'<div class="title">',
'<span class="name"><%- element.name %></span>',
"</div>",
'<div class="subtitle"></div>',
"</div>",
],
"element"
);
var subtitleTemplate = BASE_MVC.wrapTemplate([
// override this
'<div class="subtitle"></div>',
]);
var detailsTemplate = BASE_MVC.wrapTemplate([
// override this
'<div class="details"></div>',
]);
return {
el: elTemplato,
warnings: warnings,
titleBar: titleBarTemplate,
subtitle: subtitleTemplate,
details: detailsTemplate,
};
})();
//==============================================================================
/** A view that is displayed in some larger list/grid/collection.
* *AND* can display some sub-list of it's own when expanded (e.g. dataset collections).
* This list will 'foldout' when the item is expanded depending on this.foldoutStyle:
* If 'foldout': will expand vertically to show the nested list
* If 'drilldown': will overlay the parent list
*
* Inherits from ListItemView.
*
* _renderDetails does the work of creating this.details: a sub-view that shows the nested list
*/
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.)
*/
foldoutStyle: "foldout",
/** Panel view class to instantiate for the sub-panel */
foldoutPanelClass: null,
/** override to:
* add attributes foldoutStyle and foldoutPanelClass for config poly
* disrespect attributes.expanded if drilldown
*/
initialize: function (attributes) {
if (this.foldoutStyle === "drilldown") {
this.expanded = false;
}
this.foldoutStyle = attributes.foldoutStyle || this.foldoutStyle;
this.foldoutPanelClass = attributes.foldoutPanelClass || this.foldoutPanelClass;
ListItemView.prototype.initialize.call(this, attributes);
this.foldout = this._createFoldoutPanel();
},
/** in this override, attach the foldout panel when rendering details */
_renderDetails: function () {
if (this.foldoutStyle === "drilldown") {
return $();
}
var $newDetails = ListItemView.prototype._renderDetails.call(this);
return this._attachFoldout(this.foldout, $newDetails);
},
/** In this override, handle collection expansion. */
_createFoldoutPanel: function () {
var model = this.model;
var FoldoutClass = this._getFoldoutPanelClass(model);
var options = this._getFoldoutPanelOptions(model);
return new FoldoutClass(
_.extend(options, {
model: model,
})
);
},
/** Stub to return proper foldout panel class */
_getFoldoutPanelClass: function () {
// override
return this.foldoutPanelClass;
},
/** Stub to return proper foldout panel options */
_getFoldoutPanelOptions: function () {
return {
// propagate foldout style down
foldoutStyle: this.foldoutStyle,
fxSpeed: this.fxSpeed,
};
},
/** Render the foldout panel inside the view, hiding controls */
_attachFoldout: function (foldout, $whereTo) {
$whereTo = $whereTo || this.$("> .details");
this.foldout = foldout.render(0);
foldout.$("> .controls").hide();
return $whereTo.append(foldout.$el);
},
/** In this override, branch on foldoutStyle to show expanded */
expand: function () {
var view = this;
return view._fetchModelDetails().always(() => {
if (view.foldoutStyle === "foldout") {
view._expand();
} else if (view.foldoutStyle === "drilldown") {
view._expandByDrilldown();
}
});
},
/** For drilldown, set up close handler and fire expanded:drilldown
* containing views can listen to this and handle other things
* (like hiding themselves) by listening for expanded/collapsed:drilldown
*/
_expandByDrilldown: function () {
var view = this;
// attachment and rendering done by listener
view.listenTo(view.foldout, "close", () => {
view.trigger("collapsed:drilldown", view, view.foldout);
});
view.trigger("expanded:drilldown", view, view.foldout);
},
});
// ............................................................................ TEMPLATES
/** underscore templates */
FoldoutListItemView.prototype.templates = (() => {
var detailsTemplate = BASE_MVC.wrapTemplate(
[
'<div class="details">',
// override with more info (that goes above the panel)
"</div>",
],
"collection"
);
return _.extend({}, ListItemView.prototype.templates, {
details: detailsTemplate,
});
})();
//==============================================================================
export default {
ExpandableView: ExpandableView,
ListItemView: ListItemView,
FoldoutListItemView: FoldoutListItemView,
};
File diff suppressed because it is too large Load Diff
-136
View File
@@ -1,136 +0,0 @@
import _ from "underscore";
import $ from "jquery";
import _l from "utils/localization";
import { getGalaxyInstance } from "app";
//TODO: toastr is another possibility - I didn't see where I might add details, tho
/* ============================================================================
Error modals meant to replace the o-so-easy alerts.
These are currently styled as errormessages but use the Galaxy.modal
infrastructure to be shown/closed. They're capable of showing details in a
togglable dropdown and the details are formatted in a pre.
Example:
errorModal( 'Heres a message', 'A Title', { some_details: 'here' });
errorModal( 'Heres a message' ); // no details, title is 'Error'
There are three specialized forms:
offlineErrorModal a canned response for when there's no connection
badGatewayErrorModal canned response for when Galaxy is restarting
ajaxErrorModal plugable into any Backbone class as an
error event handler by accepting the error args: model, xhr, options
Examples:
if( navigator.offLine ){ offlineErrorModal(); }
if( xhr.status === 502 ){ badGatewayErrorModal(); }
this.listenTo( this.model, 'error', ajaxErrorModal );
============================================================================ */
var CONTACT_MSG = _l("Please contact a Galaxy administrator if the problem persists.");
var DEFAULT_AJAX_ERR_MSG = _l("An error occurred while updating information with the server.");
var DETAILS_MSG = _l("The following information can assist the developers in finding the source of the error:");
/** private helper that builds the modal and handles adding details */
function _errorModal(message, title, details) {
const Galaxy = getGalaxyInstance();
// create and return the modal, adding details button only if needed
Galaxy.modal.show({
title: title,
body: message,
closing_events: true,
buttons: {
Ok: function () {
Galaxy.modal.hide();
},
},
});
Galaxy.modal.$el.addClass("error-modal");
if (details) {
Galaxy.modal.$(".error-details").add(Galaxy.modal.$('button:contains("Details")')).remove();
$("<div/>")
.addClass("error-details")
.hide()
.appendTo(Galaxy.modal.$(".modal-content"))
.append([$("<p/>").text(DETAILS_MSG), $("<pre/>").text(JSON.stringify(details, null, " "))]);
$(`<button id="button-1" class="float-left">${_l("Details")}</button>`)
.appendTo(Galaxy.modal.$(".buttons"))
.click(() => {
Galaxy.modal.$(".error-details").toggle();
});
}
return Galaxy.modal;
}
/** Display a modal showing an error message but fallback to alert if there's no modal */
function errorModal(message, title, details) {
if (!message) {
return;
}
const Galaxy = getGalaxyInstance();
message = _l(message);
title = _l(title) || _l("Error:");
if (Galaxy && Galaxy.modal) {
return _errorModal(message, title, details);
}
alert(`${title}\n\n${message}`);
console.log("error details:", JSON.stringify(details));
}
// ----------------------------------------------------------------------------
/** display a modal when the user may be offline */
function offlineErrorModal() {
return errorModal(_l("You appear to be offline. Please check your connection and try again."), _l("Offline?"));
}
// ----------------------------------------------------------------------------
/** 502 messages that should be displayed when galaxy is restarting */
function badGatewayErrorModal() {
return errorModal(
`${_l("Galaxy is currently unreachable. Please try again in a few minutes.")} ${CONTACT_MSG}`,
_l("Cannot connect to Galaxy")
);
}
// ----------------------------------------------------------------------------
/** display a modal (with details) about a failed Backbone ajax operation */
function ajaxErrorModal(model, xhr, options, message, title) {
message = message || DEFAULT_AJAX_ERR_MSG;
message += ` ${CONTACT_MSG}`;
title = title || _l("An error occurred");
var details = _ajaxDetails(model, xhr, options);
return errorModal(message, title, details);
}
/** build details which may help debugging the ajax call */
function _ajaxDetails(model, xhr, options) {
const Galaxy = getGalaxyInstance();
return {
sentry: Galaxy?.Sentry.lastEventId(),
userAgent: navigator.userAgent,
onLine: navigator.onLine,
version: _.result(Galaxy.config, "version_major"),
xhr: _.omit(xhr, _.functions(xhr)),
options: _.omit(options, "xhr"),
// add ajax data from Galaxy object cache
url: _.result(Galaxy.lastAjax, "url"),
data: _.result(Galaxy.lastAjax, "data"),
// backbone stuff (auto-redacting email for user)
model: _.result(model, "toJSON", `${model}`),
user: _.omit(_.result(Galaxy.user, "toJSON"), "email"),
};
}
//=============================================================================
export default {
errorModal: errorModal,
offlineErrorModal: offlineErrorModal,
badGatewayErrorModal: badGatewayErrorModal,
ajaxErrorModal: ajaxErrorModal,
};
-1
View File
@@ -287,7 +287,6 @@ export default {
RadioButton: Options.RadioButton,
Checkbox: Options.Checkbox,
Radio: Options.Radio,
Switch: Switch,
Select: Select,
NullableText: NullableText,
TextSelect: TextSelect,
-51
View File
@@ -1,51 +0,0 @@
//Allow change tab on event=====================================================
function change_favicon(img) {
var favicon = document.createElement("link");
favicon.id = "tabicon";
favicon.setAttribute("rel", "shortcut icon");
var head = document.querySelector("head");
head.appendChild(favicon);
favicon.setAttribute("type", "image/png");
favicon.setAttribute("href", img);
}
//Check if browser is hidden-aware==============================================
function hidden_permit() {
var browsers = ["webkit", "moz", "ms", "o"];
if ("hidden" in document) {
return "hidden";
}
for (var i = 0; i < browsers.length; i++) {
if (browsers[i] + "Hidden" in document) {
return browsers[i] + "Hidden";
}
}
return null;
}
//Find out if browser tab is hidden=============================================
function is_hidden() {
var state = hidden_permit();
if (!state) {
return false;
}
return document[state];
}
//Generate new tab message to display on update in window=======================
function hidden_count(current) {
if (is_hidden()) {
if (current === 1) {
document.title = "Galaxy (1 job completed)";
} else {
document.title = "Galaxy (" + current + " jobs completed)";
}
}
}
export default {
change_favicon: change_favicon,
hidden_permit: hidden_permit,
is_hidden: is_hidden,
hidden_count: hidden_count,
};
@@ -5,7 +5,7 @@ import $ from "jquery";
import Backbone from "backbone";
import { getGalaxyInstance } from "app";
import Utils from "utils/utils";
import Portlet from "mvc/ui/ui-portlet";
import Portlet from "./portlet";
import Ui from "mvc/ui/ui-misc";
export var View = Backbone.View.extend({
@@ -1,4 +1,4 @@
import Webhooks from "mvc/webhooks";
import Webhooks from "utils/webhooks";
import Utils from "utils/utils";
export function onloadWebhooks(Galaxy) {
+5 -17
View File
@@ -6,6 +6,7 @@
// Bootstrap-related style overrides
@import "overrides.scss";
@import "mixins.scss";
// Fontawesome configuration.
//$fa-font-path: "../../../node_modules/font-awesome/fonts/";
@@ -39,6 +40,10 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free/webfonts/";
@import "toolshed.scss";
@import "workflow.scss";
@import "multiselect.scss";
@import "icon-btn.scss";
@import "peek-columns.scss";
@import "dataset.scss";
@import "list-item.scss";
// ==== Select2 ====
/* fix for zero width select2 - remove when fixed there */
@@ -57,24 +62,7 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free/webfonts/";
color: $text-color;
}
// ==== Mixins ====
@mixin user-select($select) {
-webkit-touch-callout: #{$select};
@each $pre in -webkit-, -moz-, -ms-, -o-, -khtml- {
#{$pre + user-select}: #{$select};
}
#{user-select}: #{$select};
}
@mixin border-radius($radius) {
// from font-awesome 3.0
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
// ==== Basic styles ====
body {
@extend .m-2;
}
-62
View File
@@ -1,62 +0,0 @@
//============================================================================= collection element
.dataset-collection-element {
@extend .has-job-state-mixin;
.title-bar {
.subtitle {
margin-top: 2px;
}
}
.details {
display: none;
}
}
//.dataset-collection-element.dataset {
//}
//
//.dataset-collection-element.dataset-collection {
//}
//============================================================================= collection
.history-content.dataset-collection {
@extend .has-job-state-mixin;
}
//============================================================================= collection panel
.dataset-collection-panel {
@extend .flex-vertical-container;
.vertically-spaced {
margin-top: 4px;
}
> .controls {
@extend .mx-3;
.navigation {
.back {
span {
font-weight: bold;
}
}
}
.title {
.name {
font-weight: bold;
}
}
}
> .list-items {
@extend .flex-column;
overflow-x: hidden;
overflow-y: auto;
}
}
.collection-progress {
.progress {
border: $border-default;
border-color: $text-muted;
.progress-bar {
color: $text-muted;
}
}
}
-353
View File
@@ -1,353 +0,0 @@
@import "scss/mixins";
// all histories
.history-panel {
@extend .flex-vertical-container;
> .controls {
@extend .px-3;
flex: 0 0 auto;
.title {
.name {
margin-left: -1px;
}
input {
font-weight: bold;
}
}
.subtitle:not(:empty) {
span + span:before {
content: ", ";
}
}
.history-size {
float: left;
@extend .mt-1;
}
.actions {
&:empty {
height: $icon-btn-size;
}
}
.messages {
clear: both;
.quota-message {
display: none;
}
}
//TODO: move these out
.annotation-display {
display: none;
margin-bottom: 8px;
color: $text-muted;
.prompt {
display: block;
margin: 0px;
padding: 0px;
font-size: 90%;
font-weight: normal;
}
.prompt:after {
content: ":";
}
}
.annotation-display {
.annotation {
background: white;
border-radius: 3px;
border: 1px solid fade-out($border-color, 0.5);
padding: 4px;
white-space: pre-wrap;
overflow: auto;
}
// fake placeholder for editable text annotation
.annotation:empty:after {
position: relative;
top: -4px;
font-size: 10px;
font-style: italic;
color: $text-muted;
//TODO: move out for localization
content: "Click here to edit annotation";
}
textarea {
margin: 0px 0px 2px 0px;
//display: block;
border-radius: 3px;
width: 100%;
}
}
.list-pagination {
width: 100%;
text-align: center;
margin: 0;
border-top: 1px solid $btn-default-border;
button {
margin: 0;
padding: 0;
width: 25%;
max-width: 128px;
height: 20px;
color: transparent;
overflow: hidden;
}
.pages {
// restyle closer to button
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
margin: 0;
padding: 0;
width: 48%;
max-width: 256px;
height: 20px;
box-shadow: none;
text-align: center;
text-align-last: center;
&:focus {
outline: none;
}
&:hover {
cursor: pointer;
}
}
&:empty {
display: none;
}
& > * {
border: none;
border-radius: 0px;
background: transparent;
&.pages {
color: $text-muted;
text-decoration: underline;
}
&:hover,
&:focus,
&:active {
background: $btn-default-bg;
color: $btn-default-color;
box-shadow: none;
text-decoration: none;
}
}
&:hover > *:not([disabled]) {
color: $btn-default-color;
}
}
}
// the help text that appears above the drop target
.history-drop-target-help {
margin: 10px 10px 4px 10px;
color: $text-muted;
font-size: 80%;
font-style: italic;
text-align: center;
}
.history-drop-target {
min-height: 64px;
margin: 0px 10px 10px 10px;
border: 1px dashed black;
border-radius: 3px;
}
> .list-items {
@extend .flex-column;
overflow-x: hidden;
overflow-y: auto;
&:empty {
flex-grow: 0 !important;
}
}
> .empty-message {
@extend .m-3;
}
.loading-indicator,
.contents-loading-indicator {
display: inline-block;
width: 100%;
padding: 16px;
text-align: center;
color: $text-color;
}
.history-content.dataset,
.history-content.dataset-collection {
.title-bar {
.title {
.hid:after {
content: ":";
}
}
}
}
}
// ---------------------------------------------------------------------------- collapsed history controls
// compact the history controls when scrolling away from the top
.history-panel > .controls.collapsed {
margin: 0px;
padding: 4px 8px 4px;
flex-basis: 32px;
.messages,
.title,
.subtitle,
.history-size,
//TODO: move these out
.annotation-display .prompt {
display: none;
}
.search {
margin-bottom: 4px;
}
.actions {
margin-bottom: 0;
}
.list-pagination {
.prev,
.next {
display: none;
}
.pages {
float: left;
}
}
}
// ---------------------------------------------------------------------------- added class for wider display
// since these are rendered *within parts* of other pages, we need something more than a media query
.history-panel.wide {
& > .controls {
.actions:empty {
height: auto;
}
}
}
// ---------------------------------------------------------------------------- collections nested in histories
.history-panel {
.dataset-collection {
.subtitle {
margin-top: 2px;
}
}
}
// ---------------------------------------------------------------------------- annotated-history-panel
.annotated-history-panel {
& > .controls {
margin: 0px;
.name {
font-size: 150%;
margin-bottom: 4px;
}
// annotations are displayed by default in this view
.subtitle {
display: block;
white-space: pre-wrap;
&:empty {
display: none;
}
}
.history-size {
float: none;
margin: 0;
}
}
// defined outside of list-items because .headers is actually added to controls
// so that it will stay in place despite scrolling
.headers.contents-container {
margin-bottom: 0;
border-bottom: 2px solid grey;
cursor: unset;
& > * {
vertical-align: middle;
padding: 8px;
font-weight: bold;
}
.additional-info {
text-align: right;
}
}
.contents-container {
display: table;
table-layout: fixed;
width: 100%;
// show clickable for expansion
cursor: pointer;
border-bottom: 1px solid rgba(grey, 0.5);
& > * {
display: table-cell;
vertical-align: top;
width: 50%;
}
.additional-info:not(.header) {
/* top and bottom should be == title-bar padding */
padding: 8px;
// do not html format
white-space: pre-wrap;
}
}
& > .list-items {
width: 100%;
border-bottom: 1px solid lightgrey;
}
.empty-message {
margin-top: 8px;
}
}
// ---------------------------------------------------------------------------- embedded in pages
.embedded-item.display.history .annotated-history-panel {
& > .controls {
.name {
display: none;
}
}
}
// ---------------------------------------------------------------------------- current-history-panel
.current-history-panel {
& > .controls .list-pagination {
// text a bit smaller for all
font-size: 90%;
& > * {
font-size: inherit;
}
}
// .current-content is added to dataset/collection when displayed/edited/visualized, etc@mixin
// (roughly: when it's being used in the center panel)
.list-item.history-content.current-content {
//TODO: Galaxy's 'bs-primary' color - not sure where this is defined
border-left: 5px solid #4e5777;
}
}
// ---------------------------------------------------------------------------- analyze data page - right panel
#right.history-right-panel {
.unified-panel-body {
display: -webkit-flex;
.middle {
overflow: auto;
width: 100%;
display: -webkit-flex !important;
}
}
}
// History panel tags editor
.history-panel .tags-display {
padding: 1px;
@include shutterFade(250px);
}
-55
View File
@@ -1,55 +0,0 @@
// ---------------------------------------------------------------------------- generic panel list items
.job.list-item {
border: 1px solid $border-color;
.title-bar {
.subtitle {
color: grey;
font-size: 80%;
}
}
& > .details {
padding: 0px;
.params {
padding: 0px 8px 0px 8px;
//display: table;
.param,
.input {
//display: table-row;
.prompt {
//display: block;
//display: table-cell;
//margin-right: 8px;
//text-align: right;
font-size: 80%;
//font-style: italic;
color: grey;
}
.value {
display: inline-block;
font-weight: bold;
//display: table-cell;
}
}
}
.list-panel {
padding: 0px;
.list-items {
border: 0px;
border-radius: 0px;
.list-item {
border: 0px;
border-radius: 0px;
border-top: 1px solid $border-color;
&:last-child {
}
}
}
}
}
}
+15
View File
@@ -5,6 +5,21 @@ $fa-font-path: "../../../node_modules/@fortawesome/fontawesome-free/webfonts/";
@import "~@fortawesome/fontawesome-free/scss/fontawesome";
@import "~@fortawesome/fontawesome-free/scss/_variables";
@mixin user-select($select) {
-webkit-touch-callout: #{$select};
@each $pre in -webkit-, -moz-, -ms-, -o-, -khtml- {
#{$pre + user-select}: #{$select};
}
#{user-select}: #{$select};
}
@mixin border-radius($radius) {
// from font-awesome 3.0
-webkit-border-radius: $radius;
-moz-border-radius: $radius;
border-radius: $radius;
}
// Utility mixin expands to container edges
@mixin fill() {
position: relative;
@@ -1,93 +0,0 @@
// component to display a dataset choice and activate a modal chooser (single *and* multiple datasets)
.dataset-choice {
border: 1px solid lightgrey;
border-radius: 3px;
overflow: hidden;
padding: 10px 8px 8px 8px;
&:hover {
border-color: black;
cursor: pointer;
& > * {
cursor: pointer;
}
}
.prompt {
margin-right: 8px;
&:after {
content: ":";
}
&:empty {
display: none;
}
}
.none-selected-msg {
color: grey;
}
.selected {
display: inline-block;
.title {
font-weight: bold;
}
.subtitle {
color: grey;
&:before {
content: "-";
margin: 0px 4px 0px 4px;
}
i {
font-style: normal;
&:not(:last-child):after {
content: ", ";
}
}
}
}
}
// component to display a dataset choice and activate a modal chooser (multiple datasets)
.dataset-choice.multi {
.selected {
display: block;
font-weight: normal;
}
table {
width: 100%;
margin-top: 8px;
cursor: pointer;
&:hover {
border-color: black;
}
tr:nth-child(even) {
background-color: aliceblue;
}
th {
padding: 0px;
font-weight: normal;
font-size: 80%;
color: grey;
}
th:not(:last-child),
td:not(:last-child) {
padding-right: 8px;
}
td.cell-name {
font-weight: bold;
}
}
}
// modal allowing single or multiple dataset selection - often activated by .dataset-choice above
.dataset-choice-modal .list-panel {
.list-item.dataset {
border-left-width: 1px;
border-right-width: 1px;
}
.controls .title .name {
font-size: 120%;
}
}
-34
View File
@@ -1,34 +0,0 @@
// augmented ui-modal meant to replace alert() and display error details
.error-modal .modal-content {
@extend .errormessagelarge;
& > * {
padding: 0;
margin: 0;
border: none;
}
// error details are in modal-content after modal-body
.error-details {
display: none;
margin-top: 8px;
// after a short preamble, show the details
pre {
// error details are black & white, word-wrapped
border-radius: 3px;
background: white;
padding: 8px;
white-space: pre-wrap;
color: black;
}
}
.modal-footer {
margin-top: 8px;
// float buttons individually, not as a div
.buttons {
width: 100%;
float: none;
& > * {
float: right;
}
}
}
}
-34
View File
@@ -1,34 +0,0 @@
// pagination & scrolling pagination: see scripts/jq-plugins/ui/pagination.js
.pagination {
margin: 0px;
}
.pagination-scroll-container {
display: inline-block;
background-color: #f8f8f8;
border-radius: 3px;
border: 1px solid #bfbfbf;
overflow: auto;
}
.pagination-scroll-container .pagination-page-list {
margin: 3px 0px 3px 0px;
}
.pagination-scroll-container .pagination-page-list > li:first-child > a,
.pagination-scroll-container .pagination-page-list > li:first-child > span {
border-radius: 0px;
border-left: 0px;
}
.pagination-scroll-container .pagination-page-list > li:last-child > a,
.pagination-scroll-container .pagination-page-list > li:last-child > span {
border-radius: 0px;
}
.pagination-scroll-container .pagination-page-list > li > a {
float: none;
position: static;
border: 1px solid #bfbfbf;
border-width: 0px 0px 0px 1px;
}
@@ -1,53 +0,0 @@
.search-input {
::placeholder {
color: $text-muted;
}
border: $border-default;
border-radius: 1rem;
background: #fff;
.search-advanced,
.search-clear,
.search-loading {
@extend .mr-2;
position: relative;
float: right;
top: -27px;
font-size: 1.2rem;
color: $text-muted;
}
.search-advanced {
margin-right: 5px !important;
}
.search-advanced:hover {
color: $brand-info;
cursor: pointer;
}
.search-clear:hover {
color: $brand-info;
cursor: pointer;
}
.search-loading {
display: none;
}
.search-query {
@extend .px-3;
@extend .form-control;
outline: 0px !important;
-webkit-appearance: none;
box-shadow: none !important;
width: 100%;
display: inline-block;
font-size: $font-size-base;
line-height: $line-height-base;
color: $text-color;
border: 0px;
@include border-radius($border-radius-extralarge);
max-width: auto;
background: $white;
}
.search-query:focus {
border-color: $brand-info;
outline: 0;
}
}
-14
View File
@@ -699,20 +699,6 @@ div.permissionContainer {
padding-left: 5px;
}
// ============================================================================ History
@import "ui/icon-btn.scss";
@import "list-item.scss";
@import "dataset.scss";
@import "history.scss";
@import "collection.scss";
@import "job.scss";
@import "ui/search-input.scss";
@import "ui/dataset-choice.scss";
@import "ui/peek-column-selector.scss";
@import "ui/pagination.scss";
@import "ui/error-modal.scss";
// ==== Tool menu styles
.toolMenuContainer {
color: $panel-text-color;
@@ -1,4 +1,4 @@
import RuleDefs from "mvc/rules/rule-definitions";
import RuleDefs from "components/RuleBuilder/rule-definitions";
import SPEC_TEST_CASES from "./rules_dsl_spec.yml";
function applyRules(rules, data, sources) {