import { FramesManager } from '../../../../mel_metapage/js/lib/classes/frame_manager.js';
import { MainNav } from '../../../../mel_metapage/js/lib/classes/main_nav.js';
import { EMPTY_STRING } from '../../../../mel_metapage/js/lib/constants/constants.js';
import { MelObject } from '../../../../mel_metapage/js/lib/mel_object.js';
import { Mel_Promise } from '../../../../mel_metapage/js/lib/mel_promise.js';
import { WspNavBar } from '../WebComponents/navbar.js';
// import { WspNavBar } from './WebComponents/navbar.js';
import { CurrentWorkspaceData, WorkspaceObject } from './WorkspaceObject.js';
/**
* @callback OnBeforeSwitchCallback
* @param {Object} args
* @param {string} args.task
* @param {Event} args.event
* @returns {Object} config
*/
/**
* @callback OnAfterSwitchCallback
* @param {Object} args
* @param {string} args.task
* @param {Event} args.caller
* @returns {void}
*/
/**
* @callback ListenerSetterBeforeFunction
* @param {OnBeforeSwitchCallback} callback
* @param {string} task
* @returns {ListenersSetter}
*/
/**
* @callback ListenerSetterAfterFunction
* @param {OnAfterSwitchCallback} callback
* @param {string} task
* @returns {ListenersSetter}
*/
/**
* @typedef ListenersSetter
* @property {ListenerSetterBeforeFunction} OnBeforeSwitch
* @property {ListenerSetterAfterFunction} OnAfterSwitch
* @property {typeof NavBarManager} parent
*/
export class NavBarManager {
constructor() {}
static get nav() {
let nav = window;
{
let secu = 0;
while (nav !== parent && ++secu <= 6) {
nav = parent;
}
}
return nav;
}
/**
* @type {WspNavBar}
*/
static get currentNavBar() {
return this.nav.document.querySelector('bnum-wsp-nav');
}
/**
*
* @param {CurrentWorkspaceData} workspace
*/
static Generate(workspace) {
let nav = this.nav;
if (this.currentNavBar) this.currentNavBar.remove();
if (!nav.document.querySelector(`#navbar-${workspace.uid}`)) {
if (typeof rcmail.env.navbar === 'string')
rcmail.env.navbar = JSON.parse(rcmail.env.navbar);
/**
* @type {WspNavBar}
*/
let navbar = WspNavBar.CreateElement({
nav: nav.document,
workspace: rcmail.env.navbar.workspace,
css: rcmail.env.navbar.css,
modules: rcmail.env.navbar.module,
scripts: rcmail.env.navbar.scripts,
settings: rcmail.env.navbar.settings,
onuserchanged: () => WorkspaceObject.GetWorkspaceData().reloadUsers(),
onuserrequested: () => WorkspaceObject.GetWorkspaceData().users,
});
//nav.$(rcmail.env.navbar)[0];
navbar.startingStates = rcmail.env['workspace_modules_visibility'] ?? {};
navbar.setAttribute('id', `navbar-${workspace.uid}`);
navbar.style.marginTop = '60px';
navbar.style.marginLeft = 'var(--navbar-margin-left, 60px)';
navbar.style.marginRight = '5px';
navbar.onquitbuttonclick.push(() => {
MelObject.Empty().unload('current_wsp');
NavBarManager.nav.$('html').removeClass('mwsp');
let $html;
for (const frame of FramesManager.Instance.get_window()) {
if (frame) {
$html = frame.$frame[0].contentWindow.$('html').removeClass('mwsp');
if ($html.attr('data-added'))
$html
.removeClass($html.attr('data-added'))
.removeAttr('data-added');
}
}
$html = null;
if (FramesManager.Instance.has_frame('calendar')) {
FramesManager.Instance.get_frame('calendar')[0]
.contentWindow.$('#calendar')
.fullCalendar('refetchEvents');
}
// this.currentNavBar.remove();
// nav.$('#layout-frames').css('margin-left', EMPTY_STRING);
top.history.replaceState(
{},
document.title,
MelObject.Empty()
.url('workspace', {})
.replace('&_is_from=iframe', EMPTY_STRING),
);
MelObject.Empty()
.generate_loader('deleting', true)
.generate()
.appendTo($('body').html(EMPTY_STRING));
// window.location.href = MelObject.Empty().url('workspace', {});
this.Kill(workspace.uid);
FramesManager.Instance.switch_frame('workspace', {
args: { _action: 'index' },
});
});
navbar.onbuttonclicked.push((task, event) => {
this.SwitchPage(task, { event, workspace });
});
nav.$('#layout-frames').before(navbar).css('margin-left', '5px');
navbar = null;
}
return this;
}
static async SwitchPage(
task,
{ event = null, workspace = null, manualConfig = null } = {},
) {
const raw_config =
rcmail.triggerEvent('workspace.nav.beforeswitch', { task, event }) || {};
const config =
manualConfig || (Array.isArray(raw_config) ? raw_config[0] : raw_config);
this.currentNavBar.select(task, { background: true });
workspace ??= WorkspaceObject.GetWorkspaceData();
switch (task) {
case 'home':
$('.wsp-params').css('display', 'none');
$('#main-content').css('display', EMPTY_STRING);
await FramesManager.Instance.switch_frame('workspace', {
args: config,
actions: ['workspace'],
});
top.history.replaceState(
{},
document.title,
MelObject.Empty().url('workspace', {
action: 'workspace',
params: {
_uid: workspace.uid,
_force_bnum: 1,
},
removeIsFromIframe: true,
}),
);
break;
case 'settings':
case 'workspace_params':
this.currentNavBar.onactionclicked.call('settings');
await FramesManager.Instance.switch_frame('workspace', {
args: config,
actions: ['workspace'],
});
top.history.replaceState(
{},
document.title,
MelObject.Empty().url('workspace', {
action: 'workspace',
params: {
_uid: workspace.uid,
_page: 'settings',
_force_bnum: 1,
},
removeIsFromIframe: true,
}),
);
break;
case 'more':
case 'workspace_user':
this.currentNavBar.onactionclicked.call('more');
await FramesManager.Instance.switch_frame('workspace', {
args: config,
actions: ['workspace'],
});
top.history.replaceState(
{},
document.title,
MelObject.Empty().url('workspace', {
action: 'workspace',
params: {
_uid: workspace.uid,
_page: 'more',
_force_bnum: 1,
},
removeIsFromIframe: true,
}),
);
break;
default:
await FramesManager.Instance.switch_frame(task, {
args: config,
actions: ['workspace'],
}).then(() => {
rcmail.triggerEvent('workspace.navbar.onclick', {
task,
caller: event,
});
if (task === 'calendar') {
FramesManager.Instance.get_frame('calendar')[0]
.contentWindow.$('#calendar')
.fullCalendar('rerenderEvents');
}
FramesManager.Instance.get_frame(task, { jquery: false })
.contentWindow.$('html')
.addClass('mwsp');
const workspace_force = FramesManager.Instance.get_frame(
'workspace',
{ jquery: false },
).contentWindow.rcmail.env.workspace_force_theme;
if (workspace_force && workspace_force[task]) {
FramesManager.Instance.get_frame(task, { jquery: false })
.contentWindow.$('html')
.addClass(workspace_force[task])
.attr('data-added', workspace_force[task]);
}
MainNav.select('workspace', { context: this.nav });
top.history.replaceState(
{},
document.title,
MelObject.Empty().url('workspace', {
action: 'workspace',
params: {
_uid: workspace.uid,
_force_bnum: 1,
_page: task,
},
removeIsFromIframe: true,
}),
);
});
break;
}
}
static Kill(uid) {
let nav = this.nav;
nav.$('#layout-frames').css('margin-left', EMPTY_STRING);
let navbar = nav.document.querySelector(`#navbar-${uid}`);
for (const key of Object.keys(
rcmail._handlers_ex?.['workspace.nav.beforeswitch'] || {},
)) {
rcmail.remove_handler_ex('workspace.nav.beforeswitch', key);
}
for (const key of Object.keys(
rcmail._handlers_ex?.['workspace.navbar.onclick'] || {},
)) {
rcmail.remove_handler_ex('workspace.navbar.onclick', key);
}
top.rcmail.add_event_listener_ex('switch_frame', 'workspace', () => {});
if (navbar) {
navbar.remove();
navbar = null;
}
}
/**
* @static
* @returns {ListenersSetter}
*/
static AddEventListener() {
return {
OnBeforeSwitch(callback, task) {
rcmail.add_event_listener_ex(
'workspace.nav.beforeswitch',
task,
callback,
);
return this;
},
OnAfterSwitch(callback, task) {
rcmail.add_event_listener_ex(
'workspace.navbar.onclick',
task,
callback,
);
return this;
},
parent: this,
};
}
static Hide() {
this.currentNavBar.hide();
return this;
}
static Show() {
this.currentNavBar.show();
return this;
}
/**
* Attend que la barre de navigation soit chargée
* @param {Object} [param0={}] Paramètre optionnel
* @param {number} [param0.waiting_time=5] Temps d'attente en seconde. Mettez `Infinity` pour un temps d'attente infinie
* @returns {Promise<boolean>} Si la barre de navigation est chargée ou non
* @async
*/
static async WaitLoading({ waiting_time = 5 } = {}) {
if (!NavBarManager.currentNavBar)
await Mel_Promise.wait(() => !!NavBarManager.currentNavBar, waiting_time);
return !!NavBarManager.currentNavBar;
}
}