diff --git a/dist/components/header.d.ts b/dist/components/header.d.ts
index 8adfcde..6975783 100644
--- a/dist/components/header.d.ts
+++ b/dist/components/header.d.ts
@@ -52,24 +52,29 @@ export interface IAppHeaderOptions {
* a list of links that should be shown in the right menu
*/
rightMenu?: IHeaderLink[];
+ /**
+ * show/hide the about dialog link
+ * @default true
+ */
showAboutLink?: boolean | ((title: HTMLElement, content: HTMLElement) => void);
/**
* show/hide the options link
- * default: false
+ * @default false
*/
showOptionsLink?: boolean | ((title: HTMLElement, content: HTMLElement) => void);
/**
* show/hide the bug report link
- * default: true
+ * @default true
*/
showReportBugLink?: boolean | ((title: HTMLElement, content: HTMLElement) => void);
/**
* show/hide the EU cookie disclaimer bar from `cookie-bar.eu`
+ * @default false
*/
showCookieDisclaimer?: boolean;
/**
* show help link true or the url to link
- * default: false
+ * @default false
*/
showHelpLink?: boolean | string;
}
@@ -91,14 +96,6 @@ export declare class AppHeader {
* Right menu is positioned to the right of the document
*/
rightMenu: HTMLElement;
- /**
- * About dialog
- */
- aboutDialog: HTMLElement;
- /**
- * Options dialog
- */
- optionsDialog: HTMLElement;
/**
* Constructor overrides the default options with the given options
* @param parent
@@ -114,9 +111,10 @@ export declare class AppHeader {
wait(): void;
ready(): void;
private static setVisibility;
- toggleOptionsLink(isVisible: boolean, contentGenerator?: (title: HTMLElement, content: HTMLElement) => void): void;
- toggleHelpLink(isVisible: boolean, helpUrl?: string): void;
- toggleReportBugLink(isVisible: boolean, contentGenerator?: (title: HTMLElement, content: HTMLElement) => void): void;
+ private openModalDialog;
+ private toggleOptionsLink;
+ private toggleHelpLink;
+ private toggleReportBugLink;
private toggleAboutLink;
hideDialog(selector: string): void;
showAndFocusOn(selector: string, focusSelector: string): void;
diff --git a/dist/components/header.js b/dist/components/header.js
index 05b00fe..f8f3af5 100644
--- a/dist/components/header.js
+++ b/dist/components/header.js
@@ -6,6 +6,7 @@ import { BaseUtils, I18nextManager } from 'phovea_core';
import '../webpack/_bootstrap';
import { BuildInfo } from './buildInfo';
import { AppMetaDataUtils } from './metaData';
+import { Dialog } from './dialogs';
/**
* header html template declared inline so we can use i18next
*/
@@ -25,19 +26,19 @@ const getTemplate = () => {
-
-
+
${I18nextManager.getInstance().i18n.t('phovea:ui.openOptionsDialog')}
-
-
+
${I18nextManager.getInstance().i18n.t('phovea:ui.openAboutDialog')}
-
-
+
${I18nextManager.getInstance().i18n.t('phovea:ui.reportBug')}
@@ -56,68 +57,7 @@ const getTemplate = () => {
-
-
-
-
-
-
-
-
-
-
+
`);
};
@@ -197,28 +137,33 @@ export interface IAppHeaderOptions {
*/
rightMenu?: IHeaderLink[];
+ /**
+ * show/hide the about dialog link
+ * @default true
+ */
showAboutLink?: boolean | ((title: HTMLElement, content: HTMLElement) => void);
/**
* show/hide the options link
- * default: false
+ * @default false
*/
showOptionsLink?: boolean | ((title: HTMLElement, content: HTMLElement) => void);
/**
* show/hide the bug report link
- * default: true
+ * @default true
*/
showReportBugLink?: boolean | ((title: HTMLElement, content: HTMLElement) => void);
/**
* show/hide the EU cookie disclaimer bar from `cookie-bar.eu`
+ * @default false
*/
showCookieDisclaimer?: boolean;
/**
* show help link true or the url to link
- * default: false
+ * @default false
*/
showHelpLink?: boolean | string;
}
@@ -268,6 +213,11 @@ export class AppHeader {
*/
rightMenu: [],
+ /**
+ * show/hide the options link
+ */
+ showAboutLink: true,
+
/**
* show/hide the options link
*/
@@ -299,16 +249,6 @@ export class AppHeader {
*/
rightMenu: HTMLElement;
- /**
- * About dialog
- */
- aboutDialog: HTMLElement;
-
- /**
- * Options dialog
- */
- optionsDialog: HTMLElement;
-
/**
* Constructor overrides the default options with the given options
* @param parent
@@ -369,14 +309,12 @@ export class AppHeader {
this.mainMenu = this.parent.querySelector('*[data-header="mainMenu"]');
this.rightMenu = this.parent.querySelector('*[data-header="rightMenu"]');
- this.aboutDialog = this.parent.querySelector('*[data-header="about"]');
- this.optionsDialog = this.parent.querySelector('*[data-header="options"]');
// show/hide links
- this.toggleOptionsLink(this.options.showOptionsLink !== false, typeof this.options.showOptionsLink === 'function' ? this.options.showOptionsLink : null);
- this.toggleAboutLink(this.options.showAboutLink !== false, typeof this.options.showAboutLink === 'function' ? this.options.showAboutLink : null);
- this.toggleReportBugLink(this.options.showReportBugLink !== false, typeof this.options.showReportBugLink === 'function' ? this.options.showReportBugLink : null);
- this.toggleHelpLink(this.options.showHelpLink !== false, typeof this.options.showHelpLink === 'string' ? this.options.showHelpLink : null);
+ this.toggleOptionsLink(this.options.showOptionsLink);
+ this.toggleAboutLink(this.options.showAboutLink);
+ this.toggleReportBugLink(this.options.showReportBugLink);
+ this.toggleHelpLink(this.options.showHelpLink);
this.options.mainMenu.forEach((l) => this.addMainMenu(l.name, l.action, l.href));
this.options.rightMenu.forEach((l) => this.addRightMenu(l.name, l.action, l.href));
@@ -414,66 +352,74 @@ export class AppHeader {
element.classList.toggle('hidden', !isVisible);
}
- toggleOptionsLink(isVisible: boolean, contentGenerator?: (title: HTMLElement, content: HTMLElement) => void) {
- const link = this.parent.querySelector('*[data-header="optionsLink"]');
- AppHeader.setVisibility(link, isVisible);
+ private openModalDialog({link, contentGenerator, title, cssClass}: {link: HTMLAnchorElement, contentGenerator: (title: HTMLElement, content: HTMLElement) => void, title: string, cssClass?: string}) {
+ link.addEventListener('click', (evt) => {
+ // stop event from jQuery/Bootstrap propagation
+ evt.preventDefault();
+ evt.stopPropagation();
+
+ const dialog = Dialog.generateDialog(title, I18nextManager.getInstance().i18n.t('phovea:ui.close'), cssClass);
+ contentGenerator(dialog.header.querySelector('.modal-title'), dialog.body);
+ dialog.show();
+
+ return false;
+ });
+ }
+
+ private toggleOptionsLink(link: boolean | ((title: HTMLElement, content: HTMLElement) => void)) {
+ const isVisible = !!link; // cast to boolean
+ const listItem = this.parent.querySelector('[data-header="optionsLink"]');
+ AppHeader.setVisibility(listItem, isVisible);
// set the URL to GitHub issues dynamically
if (isVisible) {
- contentGenerator = contentGenerator || defaultOptionsInfo;
- import('jquery').then((jquery) => {
- $('#headerOptionsDialog').one('show.bs.modal', () => {
- const content = this.parent.querySelector('*[data-header="options"]');
- const title = this.parent.querySelector('#headerOptionsDialog .modal-title');
- content.innerHTML = 'Loading...';
- contentGenerator(title, content);
- });
+ this.openModalDialog({
+ link: listItem.querySelector('a'),
+ title: I18nextManager.getInstance().i18n.t('phovea:ui.options'),
+ contentGenerator: (typeof link === 'function') ? link : defaultOptionsInfo,
+ cssClass: 'header-options-dialog'
});
}
}
- toggleHelpLink(isVisible: boolean, helpUrl?: string) {
- const link = this.parent.querySelector('*[data-header="helpLink"]');
- AppHeader.setVisibility(link, isVisible);
+ private toggleHelpLink(link: boolean | string) {
+ const isVisible = !!link; // cast to boolean
+ const listItem = this.parent.querySelector('[data-header="helpLink"]');
+ AppHeader.setVisibility(listItem, isVisible);
- if (isVisible && helpUrl) {
- link.querySelector('a')!.href = helpUrl;
+ if (isVisible && typeof link === 'string') {
+ listItem.querySelector('a').href = link;
}
}
- toggleReportBugLink(isVisible: boolean, contentGenerator?: (title: HTMLElement, content: HTMLElement) => void) {
- const link = this.parent.querySelector('*[data-header="bugLink"]');
- AppHeader.setVisibility(link, isVisible);
+ private toggleReportBugLink(link: boolean | ((title: HTMLElement, content: HTMLElement) => void)) {
+ const isVisible = !!link; // cast to boolean
+ const listItem = this.parent.querySelector('[data-header="bugLink"]');
+ AppHeader.setVisibility(listItem, isVisible);
// set the URL to GitHub issues dynamically
if (isVisible) {
- contentGenerator = contentGenerator || defaultBuildInfo;
- import('jquery').then((jquery) => {
- $('#headerReportBugDialog').one('show.bs.modal', () => {
- const content = this.parent.querySelector('*[data-header="bug"]');
- const title = this.parent.querySelector('#headerReportBugDialog .modal-title');
- content.innerHTML = 'Loading...';
- contentGenerator(title, content);
- });
+ this.openModalDialog({
+ link: listItem.querySelector('a'),
+ title: I18nextManager.getInstance().i18n.t('phovea:ui.reportBug'),
+ contentGenerator: (typeof link === 'function') ? link : defaultBuildInfo,
+ cssClass: 'header-report-bug-dialog'
});
}
}
- private toggleAboutLink(isVisible: boolean, contentGenerator?: (title: HTMLElement, content: HTMLElement) => void) {
- const link = this.parent.querySelector('*[data-header="aboutLink"]');
- AppHeader.setVisibility(link, isVisible);
+ private toggleAboutLink(link: boolean | ((title: HTMLElement, content: HTMLElement) => void)) {
+ const isVisible = !!link; // cast to boolean
+ const listItem = this.parent.querySelector('[data-header="aboutLink"]');
+ AppHeader.setVisibility(listItem, isVisible);
+
if (isVisible) {
- contentGenerator = contentGenerator || defaultAboutInfo;
- const modifyDialogOnce = () => {
- // request last deployment data
- const content = this.aboutDialog;
- const title = this.aboutDialog.parentElement.querySelector('.modal-title');
-
- contentGenerator(title, content);
- // remove event listener to prevent another DOM modification
- link.removeEventListener('click', modifyDialogOnce);
- };
- link.addEventListener('click', modifyDialogOnce);
+ this.openModalDialog({
+ link: listItem.querySelector('a'),
+ title: I18nextManager.getInstance().i18n.t('phovea:ui.about'),
+ contentGenerator: (typeof link === 'function') ? link : defaultAboutInfo,
+ cssClass: 'header-about-dialog'
+ });
}
}
@@ -499,8 +445,8 @@ export class AppHeader {
}
-
function defaultBuildInfo(_title: HTMLElement, content: HTMLElement) {
+ content.innerHTML = I18nextManager.getInstance().i18n.t('phovea:ui.loading');
BuildInfo.build().then((buildInfo) => {
content.innerHTML = buildInfo.toHTML();
}).catch((error) => {
@@ -509,6 +455,17 @@ function defaultBuildInfo(_title: HTMLElement, content: HTMLElement) {
}
function defaultAboutInfo(title: HTMLElement, content: HTMLElement) {
+ content.innerHTML = `
${I18nextManager.getInstance().i18n.t('phovea:ui.loading')}
+ `;
+
content = content.querySelector('.metaData');
AppMetaDataUtils.getMetaData().then((metaData) => {
title.innerHTML = (metaData.displayName || metaData.name).replace('_', ' ');
diff --git a/src/scss/components/_header_navbar.scss b/src/scss/components/_header_navbar.scss
index 397f2e4..d8e15d7 100644
--- a/src/scss/components/_header_navbar.scss
+++ b/src/scss/components/_header_navbar.scss
@@ -82,8 +82,17 @@ nav.navbar-inverse {
}
}
+.header-about-dialog,
+.header-report-bug-dialog,
+.header-options-dialog {
+ // hide modal dialog footer for all header dialogs
+ .modal-footer {
+ display: none;
+ }
+}
+
// aboutDialog dialog that opens from a link in the header
-#headerAboutDialog {
+.header-about-dialog {
.modal-title {
text-transform: capitalize;
}
@@ -91,25 +100,21 @@ nav.navbar-inverse {
.caleydoInfo {
margin-top: 15px;
display: flex;
- align-items: center;
+ align-items: flex-start;
+ gap: 15px;
.logo {
width: 100px;
- margin-right: 15px;
img {
width: 100%;
}
}
-
- p {
- margin-bottom: 0;
- }
}
}
-#headerReportBugDialog {
- *[data-header="bug"] textarea {
+.header-report-bug-dialog {
+ textarea {
width: 100%;
height: 25vh;
overflow: auto;