Skip to content

Commit

Permalink
Merge pull request #9822 from jmchilton/masthead_improvements_1
Browse files Browse the repository at this point in the history
More reactive, tested Masthead.
  • Loading branch information
dannon authored May 28, 2020
2 parents da71772 + 4c272a0 commit aeba343
Show file tree
Hide file tree
Showing 9 changed files with 422 additions and 466 deletions.
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

0 comments on commit aeba343

Please sign in to comment.