diff --git a/.ci/jenkins/integration-py3/run_tests.sh b/.ci/jenkins/integration-py3/run_tests.sh
index b45d68d67b5..ffc6c87e98c 100755
--- a/.ci/jenkins/integration-py3/run_tests.sh
+++ b/.ci/jenkins/integration-py3/run_tests.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-./run_tests.sh --dockerize --python3 --db postgres --clean_pyc --integration "$@"
+DOCKER_RUN_EXTRA_ARGS="--privileged" ./run_tests.sh --dockerize --python3 --db postgres --clean_pyc --integration "$@"
diff --git a/.ci/jenkins/integration/run_tests.sh b/.ci/jenkins/integration/run_tests.sh
index f5b8f320f8e..4119aef60b2 100755
--- a/.ci/jenkins/integration/run_tests.sh
+++ b/.ci/jenkins/integration/run_tests.sh
@@ -1,3 +1,3 @@
#!/bin/bash
-./run_tests.sh --dockerize --db postgres --clean_pyc --integration "$@"
+DOCKER_RUN_EXTRA_ARGS="--privileged" ./run_tests.sh --dockerize --db postgres --clean_pyc --integration "$@"
diff --git a/client/README.md b/client/README.md
index a73a76a222c..1eee5fbe0c2 100644
--- a/client/README.md
+++ b/client/README.md
@@ -4,11 +4,18 @@ Client Build System
Installs, stages, and builds the client-side scripts necessary for running the
Galaxy webapp. There's no need to use this system unless you are modifying or
developing client-side scripts, or are running the development branch of
-Galaxy.
+Galaxy. When started through `run.sh` or any other method that utilizes
+`common_startup.sh`, Galaxy will also (since 18.09) *automatically* build
+the client as a part of server startup, when it detects changes, unless that
+functionality is explicitly disabled.
-The base dependencies you will need are Node.js and Yarn. On OSX the easiest
-way to get set up is using homebrew and the command `brew install nodejs yarn`.
-More information including instructions for other platforms is available at
+The base dependencies used are Node.js and Yarn. Galaxy now includes these in
+the virtual environment, and they can be accessed by activating that with
+`source .venv/bin/activate` from the Galaxy root directory.
+
+If you'd like to install your own dependencies, on OSX the easiest way to get
+set up is using homebrew and the command `brew install nodejs yarn`. More
+information including instructions for other platforms is available at
nodejs.org and yarnpkg.com.
The Galaxy client build has necessarily grown more complex in the past several
@@ -22,11 +29,11 @@ https://gitter.im/galaxyproject/Lobby.
Complete Client Build
================================================
-There are many moving parts to the client build system, but the entrypoint for
+There are many moving parts to the client build system, but the entry point for
most people is the 'client' rule in the Makefile at the root of the Galaxy
repository. Execute the following to perform a complete build suitable for
local development, including dependency staging, style building, script
-processing and bundling. This is a development-specific build which includes
+processing, and bundling. This is a development-specific build which includes
extra debugging features, and excludes several production optimizations made
during the build process.
@@ -57,19 +64,21 @@ This will first stage any dependencies (yarn-installed packages like jquery,
etc), and then will watch for changes in any of the galaxy client source files.
When a file is changed, the client will automatically rebuild, after which you
can usually force refresh your browser to see changes. Note that it is still
-recommended to run 'make client' after you are finished actively developing
-using 'make client-watch'.
+recommended to run `make client` after you are finished actively developing
+using `make client-watch`.
Changing Styles/CSS
===================
-The CSS and styling used by Galaxy is also controlled from this directory.
-Galaxy uses Sass for its styling, a superset of CSS that compiles to CSS. Sass
-files are kept in client/galaxy/style/scss. Compiled CSS is in
-static/style/blue.
+Galaxy uses Sass for its styling, which is a superset of CSS that compiles down
+to regular CSS. Most Galaxy styling source (.scss) files are kept in
+`client/galaxy/style/scss. There are additionally style blocks alongside some
+Vue components -- styles that are particular to that individual component and
+do not apply site-wide.
-As mentioned above, 'make client' will also rebuild styles. If you *only* want
-to run the style task, use the following command from the `client` directory:
+On build, the compiled css bundle is served at `/static/style/base.css`.
- yarn run style
+As mentioned above, `make client` will rebuild styles, as a part of the webpack
+build. For iterative development, "Watch Mode" rebuilds as described above do
+include style changes.
diff --git a/client/galaxy/scripts/app/index.js b/client/galaxy/scripts/app/index.js
index f7feaf2d60e..bce096831cd 100644
--- a/client/galaxy/scripts/app/index.js
+++ b/client/galaxy/scripts/app/index.js
@@ -1,2 +1,2 @@
export { setGalaxyInstance, getGalaxyInstance } from "./singleton";
-export { default as monitor } from "./monitor";
+export { default as galaxyFacade } from "./monitor";
diff --git a/client/galaxy/scripts/app/monitor.js b/client/galaxy/scripts/app/monitor.js
index 90443a2bd32..253a834fb05 100644
--- a/client/galaxy/scripts/app/monitor.js
+++ b/client/galaxy/scripts/app/monitor.js
@@ -1,26 +1,30 @@
-import { installMonitor } from "utils/installMonitor";
+// Initializes "training wheels" causing legacy references to window.Galaxy to
+// pass through the singleton accessors. All future code should access galaxy
+// through getGalaxyInstance, and rarely with setGalaxyInstance
+
import { getGalaxyInstance, setGalaxyInstance } from "app";
import { getAppRoot } from "onload/loadConfig";
-
-let proxy;
+import { serverPath } from "utils/serverPath";
const galaxyStub = {
root: getAppRoot(),
config: {}
};
-if (!proxy) {
- // force references to window.galaxy to pass through the set/get instance functions
- // The monitor is going to store Galaxy at window._monitorStorage["Galaxy"]
- Object.defineProperty(window._monitorStorage, "Galaxy", {
+if (!window.Galaxy) {
+ Object.defineProperty(window, "Galaxy", {
enumerable: true,
- configurable: false,
- get: getGalaxyInstance,
- set: newValue => setGalaxyInstance(() => newValue)
+ get: function() {
+ console.warn("accessing (get) window.Galaxy", serverPath());
+ return getGalaxyInstance() || galaxyStub;
+ },
+ set: function(newValue) {
+ console.warn("accessing (set) window.Galaxy", serverPath());
+ setGalaxyInstance(newValue);
+ }
});
-
- let existingGalaxy = getGalaxyInstance();
- proxy = installMonitor("Galaxy", existingGalaxy || galaxyStub);
+} else {
+ console.error("Detected redefinition of window.Galaxy -- skipping, but this should be investigated.", serverPath());
}
-export default proxy;
+export default window.Galaxy;
diff --git a/client/galaxy/scripts/app/singleton.js b/client/galaxy/scripts/app/singleton.js
index bab784f2af9..482ffbb6391 100644
--- a/client/galaxy/scripts/app/singleton.js
+++ b/client/galaxy/scripts/app/singleton.js
@@ -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);
@@ -18,45 +18,23 @@ export function setGalaxyInstance(factory, atTop = true) {
addLogging(newInstance, "GalaxyApp");
}
- // Debugging frame property
-
- // storage._galaxyInstance = new Proxy(newInstance, {
- // get(galaxy, prop) {
- // if (prop == "frame") {
- // console.groupCollapsed("Frame Get", serverPath());
- // console.trace();
- // console.groupEnd();
- // }
- // return galaxy[prop];
- // },
- // set(galaxy, prop, val) {
- // galaxy[prop] = val;
- // if (prop == "frame") {
- // console.groupCollapsed("Frame Set", serverPath());
- // console.log(val);
- // console.trace();
- // console.groupEnd();
- // }
- // return true;
- // }
- // });
-
storage._galaxyInstance = newInstance;
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;
}
diff --git a/client/galaxy/scripts/apps/chart.js b/client/galaxy/scripts/apps/chart.js
deleted file mode 100644
index 9f946fd0da7..00000000000
--- a/client/galaxy/scripts/apps/chart.js
+++ /dev/null
@@ -1,19 +0,0 @@
-/**
- * These props are being exported with extended.js now since
- * extended is exposing its props on window via the expose-loader
- */
-
-import Client from "mvc/visualization/chart/chart-client";
-import Datasets from "mvc/visualization/chart/utilities/datasets";
-import Series from "mvc/visualization/chart/utilities/series";
-import Jobs from "mvc/visualization/chart/utilities/jobs";
-
-export function chart(options) {
- return new Client(options);
-}
-
-export let chartUtilities = {
- Datasets: Datasets,
- Jobs: Jobs,
- Series: Series
-};
diff --git a/client/galaxy/scripts/apps/extended.js b/client/galaxy/scripts/bundleEntries.js
similarity index 61%
rename from client/galaxy/scripts/apps/extended.js
rename to client/galaxy/scripts/bundleEntries.js
index 59bd7c460f9..c630dbb4dfc 100644
--- a/client/galaxy/scripts/apps/extended.js
+++ b/client/galaxy/scripts/bundleEntries.js
@@ -1,7 +1,14 @@
+/**
+ * The big list of horrible globals we expose on window.bundleEntries.
+ *
+ * Everything that is exposed on this global variable is something that the python templates
+ * require for their hardcoded initializations. These objects are going to have to continue
+ * to exist until such time as we replace the overall application with a Vue component which
+ * will handle initializations for components individually.
+ */
+
import $ from "jquery";
import "bootstrap";
-// export { GalaxyApp } from "app";
-import { getGalaxyInstance } from "app";
export { getGalaxyInstance, setGalaxyInstance } from "app";
import WorkflowView from "mvc/workflow/workflow-view";
import { TracksterUIView } from "viz/trackster";
@@ -11,9 +18,6 @@ export { PhylovizView as phyloviz } from "viz/phyloviz";
export { SweepsterVisualization, SweepsterVisualizationView } from "viz/sweepster";
import GalaxyLibrary from "galaxy.library";
import AdminToolshed from "admin.toolshed";
-import Masthead from "layout/masthead";
-import user from "mvc/user/user-model";
-import Modal from "mvc/ui/ui-modal";
export { default as pages } from "galaxy.pages";
export { createTabularDatasetChunkedView } from "mvc/dataset/data";
import { HistoryCollection } from "mvc/history/history-model";
@@ -28,19 +32,6 @@ export { default as HDAModel } from "mvc/history/hda-model";
export { default as LegacyGridView } from "legacy/grid/grid-view";
export { create_chart, create_histogram } from "reports/run_stats";
export { default as ToolshedGroups } from "toolshed/toolshed.groups";
-export { chart, chartUtilities } from "./chart";
-
-export function masthead(options) {
- let Galaxy = getGalaxyInstance();
- if (!Galaxy.user) {
- Galaxy.user = new user.User(options.user_json);
- }
- if (!Galaxy.masthead) {
- Galaxy.masthead = new Masthead.View(options);
- Galaxy.modal = new Modal.View();
- $("#masthead").replaceWith(Galaxy.masthead.render().$el);
- }
-}
export function adminToolshed(options) {
new AdminToolshed.GalaxyApp(options);
@@ -80,3 +71,32 @@ export function multiHistory(options) {
multipanel.render(0);
});
}
+
+// Previously wandering around as window.thing = thing in the onload script
+export { default as panels } from "layout/panel";
+export { show_in_overlay, hide_modal, show_message, show_modal, Modal } from "layout/modal";
+export { make_popupmenu, make_popup_menus } from "ui/popupmenu";
+export { default as async_save_text } from "utils/async-save-text";
+
+// Previously "chart"
+import Client from "mvc/visualization/chart/chart-client";
+import Datasets from "mvc/visualization/chart/utilities/datasets";
+import Series from "mvc/visualization/chart/utilities/series";
+import Jobs from "mvc/visualization/chart/utilities/jobs";
+
+export function chart(options) {
+ return new Client(options);
+}
+
+export let chartUtilities = {
+ Datasets: Datasets,
+ Jobs: Jobs,
+ Series: Series
+};
+
+export { initMasthead } from "components/Masthead/initMasthead";
+export { panelManagement } from "onload/globalInits/panelManagement";
+export { init_tag_click_function } from "ui/autocom_tagging";
+
+// Used in common.mako
+export { default as store } from "store";
diff --git a/client/galaxy/scripts/components/GalaxyLoader.vue b/client/galaxy/scripts/components/GalaxyLoader.vue
new file mode 100644
index 00000000000..a21b2a37604
--- /dev/null
+++ b/client/galaxy/scripts/components/GalaxyLoader.vue
@@ -0,0 +1,162 @@
+
+