Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

More reactive, tested Masthead. #9822

Merged
merged 11 commits into from
May 28, 2020
50 changes: 40 additions & 10 deletions client/galaxy/scripts/components/Masthead/Masthead.test.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import Masthead from "./Masthead.vue";
import { default as Masthead, __RewireAPI__ as rewire } from "./Masthead.vue";
import { mount, createLocalVue } from "@vue/test-utils";
import Scratchbook from "layout/scratchbook";

Expand All @@ -7,8 +7,25 @@ describe("Masthead.vue", () => {
let localVue;
let scratchbook;
let quotaRendered, quotaEl;
let tabs;

function stubFetchMenu() {
return tabs;
}

function stubLoadWebhooks(items) {
items.push({
id: "extension",
title: "Extension Point",
menu: false,
url: "extension_url",
});
}

beforeEach(() => {
rewire.__Rewire__("fetchMenu", stubFetchMenu);
rewire.__Rewire__("loadWebhookMenuItems", stubLoadWebhooks);

localVue = createLocalVue();
quotaRendered = false;
quotaEl = null;
Expand All @@ -22,7 +39,7 @@ describe("Masthead.vue", () => {
},
};

const tabs = [
tabs = [
// Main Analysis Tab..
{
id: "analysis",
Expand Down Expand Up @@ -51,16 +68,15 @@ describe("Masthead.vue", () => {
tabs.push(x);
return x;
};
scratchbook = new Scratchbook({
collection: tabs,
});
const frames = scratchbook.getFrames();
scratchbook = new Scratchbook({});
const mastheadState = {
quotaMeter,
frame: scratchbook,
};

wrapper = mount(Masthead, {
propsData: {
quotaMeter,
frames,
tabs,
mastheadState,
activeTab,
appRoot: "prefix/",
},
Expand All @@ -69,13 +85,23 @@ describe("Masthead.vue", () => {
});
});

it("should disable brand when displayGalaxyBrand is true", async () => {
expect(wrapper.find(".navbar-brand-title").text()).to.equals("Galaxy");
wrapper.setProps({ brand: "Foo " });
await localVue.nextTick();
expect(wrapper.find(".navbar-brand-title").text()).to.equals("Galaxy Foo");
wrapper.setProps({ displayGalaxyBrand: false });
await localVue.nextTick();
expect(wrapper.find(".navbar-brand-title").text()).to.equals("Foo");
});

it("set quota element and renders it", () => {
expect(quotaEl).to.not.equals(null);
expect(quotaRendered).to.equals(true);
});

it("should render simple tab item links", () => {
expect(wrapper.findAll("li.nav-item").length).to.equals(5);
expect(wrapper.findAll("li.nav-item").length).to.equals(6);
// Ensure specified link title respected.
expect(wrapper.find("#analysis a").text()).to.equals("Analyze");
expect(wrapper.find("#analysis a").attributes("href")).to.equals("prefix/root");
Expand Down Expand Up @@ -109,4 +135,8 @@ describe("Masthead.vue", () => {
// await localVue.nextTick();
// expect(scratchbook.active).to.equals(true);
});

it("should load webhooks on creation", async () => {
expect(wrapper.find("#extension a").text()).to.equals("Extension Point");
});
});
107 changes: 68 additions & 39 deletions client/galaxy/scripts/components/Masthead/Masthead.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
:appRoot="appRoot"
:Galaxy="Galaxy"
v-show="!(tab.hidden === undefined ? false : tab.hidden)"
@updateScratchbookTab="updateScratchbookTab"
>
</masthead-item>
</b-navbar-nav>
Expand All @@ -33,12 +32,17 @@
<script>
import { BNavbar, BNavbarBrand, BNavbarNav } from "bootstrap-vue";
import MastheadItem from "./MastheadItem";
import _ from "underscore";
import { fetchMenu } from "layout/menu";
import { loadWebhookMenuItems } from "./_webhooks";

export default {
name: "Masthead",
props: {
brandTitle: {
displayGalaxyBrand: {
type: Boolean,
default: true,
},
brand: {
type: String,
},
brandLink: {
Expand All @@ -47,16 +51,10 @@ export default {
brandImage: {
type: String,
},
quotaMeter: {
type: Object,
},
activeTab: {
type: String,
},
tabs: {
type: Array,
},
frames: {
mastheadState: {
type: Object,
},
appRoot: {
Expand All @@ -65,6 +63,9 @@ export default {
Galaxy: {
type: Object,
},
menuOptions: {
type: Object,
},
},
components: {
BNavbar,
Expand All @@ -73,41 +74,69 @@ export default {
MastheadItem,
},
methods: {
updateScratchbookTab(tab) {
_.each(this.tabs, (tab, i) => {
if (tab.id === "enable-scratchbook") {
tab.active = !tab.active;

this.$set(this.tabs, i, {
...tab,
toggle: tab.active,
show_note: tab.active,
note_cls: tab.active && "fa fa-check",
});
}
});
addItem(item) {
this.tabs.push(item);
},
highlight(activeTab) {
this.activeTab = activeTab;
},
_tabToJson(el) {
const defaults = {
visible: true,
target: "_parent",
};
let asJson;
if (el.toJSON instanceof Function) {
asJson = el.toJSON();
} else {
asJson = el;
}
return Object.assign({}, defaults, asJson);
},
_reflectScratchbookFrames() {
const frames = this.mastheadState.frame.getFrames();
const tab = this.mastheadState.frame.buttonLoad;
tab.toggle = frames.visible;
tab.icon = (frames.visible && "fa-eye") || "fa-eye-slash";
},
},
data() {
return {
baseTabs: [],
extensionTabs: [],
};
},
computed: {
brandTitle() {
let brandTitle = this.displayGalaxyBrand ? "Galaxy " : "";
if (this.brand) {
brandTitle += this.brand;
}
return brandTitle;
},
tabs() {
const scratchbookTabs = [this.mastheadState.frame.buttonActive, this.mastheadState.frame.buttonLoad];
const tabs = [].concat(this.baseTabs, scratchbookTabs, this.extensionTabs);
return tabs.map(this._tabToJson);
},
},
created() {
this.baseTabs = fetchMenu(this.menuOptions);
loadWebhookMenuItems(this.extensionTabs);
},
mounted() {
this.quotaMeter.setElement(this.$refs["quota-meter-container"]);
this.quotaMeter.render();

const idx = _.findIndex(this.tabs, { id: "show-scratchbook" });
this.frames
this.mastheadState.quotaMeter.setElement(this.$refs["quota-meter-container"]);
this.mastheadState.quotaMeter.render();
const frames = this.mastheadState.frame.getFrames();
frames
.on("add remove", () => {
this.$set(this.tabs, idx, {
...this.tabs[idx],
note: this.frames.length(),
visible: this.frames.length() > 0,
show_note: this.frames.length() > 0,
});
const tab = this.mastheadState.frame.buttonLoad;
tab.note = String(frames.length());
tab.visible = frames.length() > 0;
tab.show_note = frames.length() > 0;
})
.on("show hide", () => {
this.$set(this.tabs, idx, {
...this.tabs[idx],
toggle: this.frames.visible,
icon: (this.frames.visible && "fa-eye") || "fa-eye-slash",
});
this._reflectScratchbookFrames();
});
},
};
Expand Down
8 changes: 1 addition & 7 deletions client/galaxy/scripts/components/Masthead/MastheadItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ export default {
};
},
iconClasses() {
console.log("in iconClasses...");
return Object.fromEntries([
["fa", true],
["toggle", this.tab.toggle],
Expand All @@ -118,13 +119,6 @@ export default {
return document.getElementById("galaxy_main");
},
},
created() {
if (this.tab.onbeforeunload) {
document.addEventListener("beforeunload", () => {
this.tab.onbeforeunload();
});
}
},
mounted() {
if (this.galaxyIframe) {
this.galaxyIframe.addEventListener("load", this.iframeListener);
Expand Down
28 changes: 28 additions & 0 deletions client/galaxy/scripts/components/Masthead/_webhooks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Webhooks from "mvc/webhooks";
import Utils from "utils/utils";

export function loadWebhookMenuItems(items) {
Webhooks.load({
type: "masthead",
callback: function (webhooks) {
webhooks.each((model) => {
const webhook = model.toJSON();
if (webhook.activate) {
const obj = {
id: webhook.id,
icon: webhook.config.icon,
url: webhook.config.url,
tooltip: webhook.config.tooltip,
/*jslint evil: true */
onclick: webhook.config.function && new Function(webhook.config.function),
visible: true,
target: "_parent",
};
items.push(obj);
// Append masthead script and styles to Galaxy main
Utils.appendScriptStyle(webhook);
}
});
},
});
}
17 changes: 3 additions & 14 deletions client/galaxy/scripts/components/Masthead/initMasthead.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,31 +2,20 @@
* Temporary function used to mount the masthead inside the current application.
* This function is exposed with the rest of the page-globals in bundledEntries.
*/
// import Vue from "vue";
// import Masthead from "./Masthead";
import Masthead from "../../layout/masthead";
import { MastheadState, mountMasthead } from "../../layout/masthead";
import $ from "jquery";

export function initMasthead(config, container) {
console.log("initMasthead");

const masthead = new Masthead.View(config);
masthead.render();

const $masthead = $("#masthead");

if (config.hide_masthead) {
$masthead.remove();
} else {
if (container) {
$(container).replaceWith(masthead.el);
const mastheadState = new MastheadState();
mountMasthead(container, config, mastheadState);
}
}

// const Component = Vue.extend(Masthead);
// return new Component({
// props: Object.keys(config),
// propsData: config,
// el: container
// });
}
Loading