@@ -0,0 +1,12 @@ | |||||
<?xml version="1.0" encoding="UTF-8"?> | |||||
<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"> | |||||
<!-- Generator: Sketch 61.2 (89653) - https://sketch.com --> | |||||
<title>Artboard</title> | |||||
<desc>Created with Sketch.</desc> | |||||
<g id="Artboard" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"> | |||||
<g id="xhiveframework" transform="translate(3.000000, 1.000000)" fill="#0089FF" fill-rule="nonzero"> | |||||
<polygon id="Path" points="9.360932 0 0 0 0 2.46232 9.360932 2.46232"></polygon> | |||||
<polygon id="Path" points="0 6.281996 0 14 2.98788 14 2.98788 8.74846 8.740172 8.74846 8.740172 6.281996"></polygon> | |||||
</g> | |||||
</g> | |||||
</svg> |
@@ -0,0 +1,656 @@ | |||||
// Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||||
// MIT License. See license.txt | |||||
/* eslint-disable no-console */ | |||||
// __('Modules') __('Domains') __('Places') __('Administration') # for translation, don't remove | |||||
xhiveframework.start_app = function () { | |||||
if (!xhiveframework.Application) return; | |||||
xhiveframework.assets.check(); | |||||
xhiveframework.provide("xhiveframework.app"); | |||||
xhiveframework.provide("xhiveframework.desk"); | |||||
xhiveframework.app = new xhiveframework.Application(); | |||||
}; | |||||
$(document).ready(function () { | |||||
if (!xhiveframework.utils.supportsES6) { | |||||
xhiveframework.msgprint({ | |||||
indicator: "red", | |||||
title: __("Browser not supported"), | |||||
message: __( | |||||
"Some of the features might not work in your browser. Please update your browser to the latest version." | |||||
), | |||||
}); | |||||
} | |||||
xhiveframework.start_app(); | |||||
}); | |||||
xhiveframework.Application = class Application { | |||||
constructor() { | |||||
this.startup(); | |||||
} | |||||
startup() { | |||||
xhiveframework.socketio.init(); | |||||
xhiveframework.model.init(); | |||||
if (xhiveframework.boot.status === "failed") { | |||||
xhiveframework.msgprint({ | |||||
message: xhiveframework.boot.error, | |||||
title: __("Session Start Failed"), | |||||
indicator: "red", | |||||
}); | |||||
throw "boot failed"; | |||||
} | |||||
this.setup_xhiveframework_vue(); | |||||
this.load_bootinfo(); | |||||
this.load_user_permissions(); | |||||
this.make_nav_bar(); | |||||
this.set_favicon(); | |||||
this.setup_analytics(); | |||||
this.set_fullwidth_if_enabled(); | |||||
this.add_browser_class(); | |||||
this.setup_energy_point_listeners(); | |||||
this.setup_copy_doc_listener(); | |||||
this.set_rtl(); | |||||
xhiveframework.ui.keys.setup(); | |||||
xhiveframework.ui.keys.add_shortcut({ | |||||
shortcut: "shift+ctrl+g", | |||||
description: __("Switch Theme"), | |||||
action: () => { | |||||
if (xhiveframework.theme_switcher && xhiveframework.theme_switcher.dialog.is_visible) { | |||||
xhiveframework.theme_switcher.hide(); | |||||
} else { | |||||
xhiveframework.theme_switcher = new xhiveframework.ui.ThemeSwitcher(); | |||||
xhiveframework.theme_switcher.show(); | |||||
} | |||||
}, | |||||
}); | |||||
xhiveframework.ui.add_system_theme_switch_listener(); | |||||
const root = document.documentElement; | |||||
// const observer = new MutationObserver(() => { | |||||
// xhiveframework.ui.set_theme(); | |||||
// }); | |||||
// observer.observe(root, { | |||||
// attributes: true, | |||||
// attributeFilter: ["data-theme-mode"], | |||||
// }); | |||||
xhiveframework.ui.set_theme(); | |||||
// page container | |||||
this.make_page_container(); | |||||
this.set_route(); | |||||
// trigger app startup | |||||
$(document).trigger("startup"); | |||||
$(document).trigger("app_ready"); | |||||
if (xhiveframework.boot.messages) { | |||||
xhiveframework.msgprint(xhiveframework.boot.messages); | |||||
} | |||||
if (xhiveframework.user_roles.includes("System Manager")) { | |||||
// delayed following requests to make boot faster | |||||
setTimeout(() => { | |||||
this.show_change_log(); | |||||
this.show_update_available(); | |||||
}, 1000); | |||||
} | |||||
if (!xhiveframework.boot.developer_mode) { | |||||
let console_security_message = __( | |||||
"Using this console may allow attackers to impersonate you and steal your information. Do not enter or paste code that you do not understand." | |||||
); | |||||
console.log(`%c${console_security_message}`, "font-size: large"); | |||||
} | |||||
this.show_notes(); | |||||
if (xhiveframework.ui.startup_setup_dialog && !xhiveframework.boot.setup_complete) { | |||||
xhiveframework.ui.startup_setup_dialog.pre_show(); | |||||
xhiveframework.ui.startup_setup_dialog.show(); | |||||
} | |||||
xhiveframework.realtime.on("version-update", function () { | |||||
var dialog = xhiveframework.msgprint({ | |||||
message: __( | |||||
"The application has been updated to a new version, please refresh this page" | |||||
), | |||||
indicator: "green", | |||||
title: __("Version Updated"), | |||||
}); | |||||
dialog.set_primary_action(__("Refresh"), function () { | |||||
location.reload(true); | |||||
}); | |||||
dialog.get_close_btn().toggle(false); | |||||
}); | |||||
// listen to build errors | |||||
this.setup_build_events(); | |||||
if (xhiveframework.sys_defaults.email_user_password) { | |||||
var email_list = xhiveframework.sys_defaults.email_user_password.split(","); | |||||
for (var u in email_list) { | |||||
if (email_list[u] === xhiveframework.user.name) { | |||||
this.set_password(email_list[u]); | |||||
} | |||||
} | |||||
} | |||||
// REDESIGN-TODO: Fix preview popovers | |||||
this.link_preview = new xhiveframework.ui.LinkPreview(); | |||||
if (!xhiveframework.boot.developer_mode) { | |||||
if (xhiveframework.user.has_role("System Manager")) { | |||||
setInterval(function () { | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.core.doctype.log_settings.log_settings.has_unseen_error_log", | |||||
args: { | |||||
user: xhiveframework.session.user, | |||||
}, | |||||
callback: function (r) { | |||||
if (r.message.show_alert) { | |||||
xhiveframework.show_alert({ | |||||
indicator: "red", | |||||
message: r.message.message, | |||||
}); | |||||
} | |||||
}, | |||||
}); | |||||
}, 600000); // check every 10 minutes | |||||
} | |||||
} | |||||
} | |||||
set_route() { | |||||
xhiveframework.flags.setting_original_route = true; | |||||
if (xhiveframework.boot && localStorage.getItem("session_last_route")) { | |||||
xhiveframework.set_route(localStorage.getItem("session_last_route")); | |||||
localStorage.removeItem("session_last_route"); | |||||
} else { | |||||
// route to home page | |||||
xhiveframework.router.route(); | |||||
} | |||||
xhiveframework.after_ajax(() => (xhiveframework.flags.setting_original_route = false)); | |||||
xhiveframework.router.on("change", () => { | |||||
$(".tooltip").hide(); | |||||
}); | |||||
} | |||||
setup_xhiveframework_vue() { | |||||
Vue.prototype.__ = window.__; | |||||
Vue.prototype.xhiveframework = window.xhiveframework; | |||||
} | |||||
set_password(user) { | |||||
var me = this; | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.core.doctype.user.user.get_email_awaiting", | |||||
args: { | |||||
user: user, | |||||
}, | |||||
callback: function (email_account) { | |||||
email_account = email_account["message"]; | |||||
if (email_account) { | |||||
var i = 0; | |||||
if (i < email_account.length) { | |||||
me.email_password_prompt(email_account, user, i); | |||||
} | |||||
} | |||||
}, | |||||
}); | |||||
} | |||||
email_password_prompt(email_account, user, i) { | |||||
var me = this; | |||||
const email_id = email_account[i]["email_id"]; | |||||
let d = new xhiveframework.ui.Dialog({ | |||||
title: __("Password missing in Email Account"), | |||||
fields: [ | |||||
{ | |||||
fieldname: "password", | |||||
fieldtype: "Password", | |||||
label: __( | |||||
"Please enter the password for: <b>{0}</b>", | |||||
[email_id], | |||||
"Email Account" | |||||
), | |||||
reqd: 1, | |||||
}, | |||||
{ | |||||
fieldname: "submit", | |||||
fieldtype: "Button", | |||||
label: __("Submit", null, "Submit password for Email Account"), | |||||
}, | |||||
], | |||||
}); | |||||
d.get_input("submit").on("click", function () { | |||||
//setup spinner | |||||
d.hide(); | |||||
var s = new xhiveframework.ui.Dialog({ | |||||
title: __("Checking one moment"), | |||||
fields: [ | |||||
{ | |||||
fieldtype: "HTML", | |||||
fieldname: "checking", | |||||
}, | |||||
], | |||||
}); | |||||
s.fields_dict.checking.$wrapper.html('<i class="fa fa-spinner fa-spin fa-4x"></i>'); | |||||
s.show(); | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.email.doctype.email_account.email_account.set_email_password", | |||||
args: { | |||||
email_account: email_account[i]["email_account"], | |||||
password: d.get_value("password"), | |||||
}, | |||||
callback: function (passed) { | |||||
s.hide(); | |||||
d.hide(); //hide waiting indication | |||||
if (!passed["message"]) { | |||||
xhiveframework.show_alert( | |||||
{message: __("Login Failed please try again"), indicator: "error"}, | |||||
5 | |||||
); | |||||
me.email_password_prompt(email_account, user, i); | |||||
} else { | |||||
if (i + 1 < email_account.length) { | |||||
i = i + 1; | |||||
me.email_password_prompt(email_account, user, i); | |||||
} | |||||
} | |||||
}, | |||||
}); | |||||
}); | |||||
d.show(); | |||||
} | |||||
load_bootinfo() { | |||||
if (xhiveframework.boot) { | |||||
this.setup_workspaces(); | |||||
xhiveframework.model.sync(xhiveframework.boot.docs); | |||||
this.check_metadata_cache_status(); | |||||
this.set_globals(); | |||||
this.sync_pages(); | |||||
xhiveframework.router.setup(); | |||||
this.setup_moment(); | |||||
if (xhiveframework.boot.print_css) { | |||||
xhiveframework.dom.set_style(xhiveframework.boot.print_css, "print-style"); | |||||
} | |||||
xhiveframework.user.name = xhiveframework.boot.user.name; | |||||
xhiveframework.router.setup(); | |||||
} else { | |||||
this.set_as_guest(); | |||||
} | |||||
} | |||||
setup_workspaces() { | |||||
xhiveframework.modules = {}; | |||||
xhiveframework.workspaces = {}; | |||||
for (let page of xhiveframework.boot.allowed_workspaces || []) { | |||||
xhiveframework.modules[page.module] = page; | |||||
xhiveframework.workspaces[xhiveframework.router.slug(page.name)] = page; | |||||
} | |||||
} | |||||
load_user_permissions() { | |||||
xhiveframework.defaults.update_user_permissions(); | |||||
xhiveframework.realtime.on( | |||||
"update_user_permissions", | |||||
xhiveframework.utils.debounce(() => { | |||||
xhiveframework.defaults.update_user_permissions(); | |||||
}, 500) | |||||
); | |||||
} | |||||
check_metadata_cache_status() { | |||||
if (xhiveframework.boot.metadata_version != localStorage.metadata_version) { | |||||
xhiveframework.assets.clear_local_storage(); | |||||
xhiveframework.assets.init_local_storage(); | |||||
} | |||||
} | |||||
set_globals() { | |||||
xhiveframework.session.user = xhiveframework.boot.user.name; | |||||
xhiveframework.session.logged_in_user = xhiveframework.boot.user.name; | |||||
xhiveframework.session.user_email = xhiveframework.boot.user.email; | |||||
xhiveframework.session.user_fullname = xhiveframework.user_info().fullname; | |||||
xhiveframework.user_defaults = xhiveframework.boot.user.defaults; | |||||
xhiveframework.user_roles = xhiveframework.boot.user.roles; | |||||
xhiveframework.sys_defaults = xhiveframework.boot.sysdefaults; | |||||
xhiveframework.ui.py_date_format = xhiveframework.boot.sysdefaults.date_format | |||||
.replace("dd", "%d") | |||||
.replace("mm", "%m") | |||||
.replace("yyyy", "%Y"); | |||||
xhiveframework.boot.user.last_selected_values = {}; | |||||
} | |||||
sync_pages() { | |||||
// clear cached pages if timestamp is not found | |||||
if (localStorage["page_info"]) { | |||||
xhiveframework.boot.allowed_pages = []; | |||||
var page_info = JSON.parse(localStorage["page_info"]); | |||||
$.each(xhiveframework.boot.page_info, function (name, p) { | |||||
if (!page_info[name] || page_info[name].modified != p.modified) { | |||||
delete localStorage["_page:" + name]; | |||||
} | |||||
xhiveframework.boot.allowed_pages.push(name); | |||||
}); | |||||
} else { | |||||
xhiveframework.boot.allowed_pages = Object.keys(xhiveframework.boot.page_info); | |||||
} | |||||
localStorage["page_info"] = JSON.stringify(xhiveframework.boot.page_info); | |||||
} | |||||
set_as_guest() { | |||||
xhiveframework.session.user = "Guest"; | |||||
xhiveframework.session.user_email = ""; | |||||
xhiveframework.session.user_fullname = "Guest"; | |||||
xhiveframework.user_defaults = {}; | |||||
xhiveframework.user_roles = ["Guest"]; | |||||
xhiveframework.sys_defaults = {}; | |||||
} | |||||
make_page_container() { | |||||
if ($("#body").length) { | |||||
$(".splash").remove(); | |||||
xhiveframework.temp_container = $("<div id='temp-container' style='display: none;'>").appendTo( | |||||
"body" | |||||
); | |||||
xhiveframework.container = new xhiveframework.views.Container(); | |||||
} | |||||
} | |||||
make_nav_bar() { | |||||
// toolbar | |||||
if (xhiveframework.boot && xhiveframework.boot.home_page !== "setup-wizard") { | |||||
xhiveframework.xhiveframework_toolbar = new xhiveframework.ui.toolbar.Toolbar(); | |||||
} | |||||
} | |||||
logout() { | |||||
var me = this; | |||||
me.logged_out = true; | |||||
return xhiveframework.call({ | |||||
method: "logout", | |||||
callback: function (r) { | |||||
if (r.exc) { | |||||
return; | |||||
} | |||||
me.redirect_to_login(); | |||||
}, | |||||
}); | |||||
} | |||||
handle_session_expired() { | |||||
if (!xhiveframework.app.session_expired_dialog) { | |||||
var dialog = new xhiveframework.ui.Dialog({ | |||||
title: __("Session Expired"), | |||||
keep_open: true, | |||||
fields: [ | |||||
{ | |||||
fieldtype: "Password", | |||||
fieldname: "password", | |||||
label: __("Please Enter Your Password to Continue"), | |||||
}, | |||||
], | |||||
onhide: () => { | |||||
if (!dialog.logged_in) { | |||||
xhiveframework.app.redirect_to_login(); | |||||
} | |||||
}, | |||||
}); | |||||
dialog.set_primary_action(__("Login"), () => { | |||||
dialog.set_message(__("Authenticating...")); | |||||
xhiveframework.call({ | |||||
method: "login", | |||||
args: { | |||||
usr: xhiveframework.session.user, | |||||
pwd: dialog.get_values().password, | |||||
}, | |||||
callback: (r) => { | |||||
if (r.message === "Logged In") { | |||||
dialog.logged_in = true; | |||||
// revert backdrop | |||||
$(".modal-backdrop").css({ | |||||
opacity: "", | |||||
"background-color": "#334143", | |||||
}); | |||||
} | |||||
dialog.hide(); | |||||
}, | |||||
statusCode: () => { | |||||
dialog.hide(); | |||||
}, | |||||
}); | |||||
}); | |||||
xhiveframework.app.session_expired_dialog = dialog; | |||||
} | |||||
if (!xhiveframework.app.session_expired_dialog.display) { | |||||
xhiveframework.app.session_expired_dialog.show(); | |||||
// add backdrop | |||||
$(".modal-backdrop").css({ | |||||
opacity: 1, | |||||
"background-color": "#4B4C9D", | |||||
}); | |||||
} | |||||
} | |||||
redirect_to_login() { | |||||
window.location.href = "/"; | |||||
} | |||||
set_favicon() { | |||||
var link = $('link[type="image/x-icon"]').remove().attr("href"); | |||||
$('<link rel="shortcut icon" href="' + link + '" type="image/x-icon">').appendTo("head"); | |||||
$('<link rel="icon" href="' + link + '" type="image/x-icon">').appendTo("head"); | |||||
} | |||||
trigger_primary_action() { | |||||
// to trigger change event on active input before triggering primary action | |||||
$(document.activeElement).blur(); | |||||
// wait for possible JS validations triggered after blur (it might change primary button) | |||||
setTimeout(() => { | |||||
if (window.cur_dialog && cur_dialog.display) { | |||||
// trigger primary | |||||
cur_dialog.get_primary_btn().trigger("click"); | |||||
} else if (cur_frm && cur_frm.page.btn_primary.is(":visible")) { | |||||
cur_frm.page.btn_primary.trigger("click"); | |||||
} else if (xhiveframework.container.page.save_action) { | |||||
xhiveframework.container.page.save_action(); | |||||
} | |||||
}, 100); | |||||
} | |||||
show_change_log() { | |||||
var me = this; | |||||
let change_log = xhiveframework.boot.change_log; | |||||
// xhiveframework.boot.change_log = [{ | |||||
// "change_log": [ | |||||
// [<version>, <change_log in markdown>], | |||||
// [<version>, <change_log in markdown>], | |||||
// ], | |||||
// "description": "ERP made simple", | |||||
// "title": "XhiveERP", | |||||
// "version": "12.2.0" | |||||
// }]; | |||||
if ( | |||||
!Array.isArray(change_log) || | |||||
!change_log.length || | |||||
window.Cypress || | |||||
cint(xhiveframework.boot.sysdefaults.disable_change_log_notification) | |||||
) { | |||||
return; | |||||
} | |||||
// Iterate over changelog | |||||
var change_log_dialog = xhiveframework.msgprint({ | |||||
message: xhiveframework.render_template("change_log", {change_log: change_log}), | |||||
title: __("Updated To A New Version 🎉"), | |||||
wide: true, | |||||
}); | |||||
change_log_dialog.keep_open = true; | |||||
change_log_dialog.custom_onhide = function () { | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.utils.change_log.update_last_known_versions", | |||||
}); | |||||
me.show_notes(); | |||||
}; | |||||
} | |||||
show_update_available() { | |||||
if (xhiveframework.boot.sysdefaults.disable_system_update_notification) return; | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.utils.change_log.show_update_popup", | |||||
}); | |||||
} | |||||
setup_analytics() { | |||||
if (window.mixpanel) { | |||||
window.mixpanel.identify(xhiveframework.session.user); | |||||
window.mixpanel.people.set({ | |||||
$first_name: xhiveframework.boot.user.first_name, | |||||
$last_name: xhiveframework.boot.user.last_name, | |||||
$created: xhiveframework.boot.user.creation, | |||||
$email: xhiveframework.session.user, | |||||
}); | |||||
} | |||||
} | |||||
add_browser_class() { | |||||
$("html").addClass(xhiveframework.utils.get_browser().name.toLowerCase()); | |||||
} | |||||
set_fullwidth_if_enabled() { | |||||
xhiveframework.ui.toolbar.set_fullwidth_if_enabled(); | |||||
} | |||||
set_rtl() { | |||||
if (xhiveframework.utils.is_rtl()) { | |||||
$('body').addClass('xhiveframework-rtl'); | |||||
} | |||||
} | |||||
show_notes() { | |||||
var me = this; | |||||
if (xhiveframework.boot.notes.length) { | |||||
xhiveframework.boot.notes.forEach(function (note) { | |||||
if (!note.seen || note.notify_on_every_login) { | |||||
var d = xhiveframework.msgprint({message: note.content, title: note.title}); | |||||
d.keep_open = true; | |||||
d.custom_onhide = function () { | |||||
note.seen = true; | |||||
// Mark note as read if the Notify On Every Login flag is not set | |||||
if (!note.notify_on_every_login) { | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.desk.doctype.note.note.mark_as_seen", | |||||
args: { | |||||
note: note.name, | |||||
}, | |||||
}); | |||||
} | |||||
// next note | |||||
me.show_notes(); | |||||
}; | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
setup_build_events() { | |||||
if (xhiveframework.boot.developer_mode) { | |||||
xhiveframework.require("build_events.bundle.js"); | |||||
} | |||||
} | |||||
setup_energy_point_listeners() { | |||||
xhiveframework.realtime.on("energy_point_alert", (message) => { | |||||
xhiveframework.show_alert(message); | |||||
}); | |||||
} | |||||
setup_copy_doc_listener() { | |||||
$("body").on("paste", (e) => { | |||||
try { | |||||
let pasted_data = xhiveframework.utils.get_clipboard_data(e); | |||||
let doc = JSON.parse(pasted_data); | |||||
if (doc.doctype) { | |||||
e.preventDefault(); | |||||
const sleep = xhiveframework.utils.sleep; | |||||
xhiveframework.dom.freeze(__("Creating {0}", [doc.doctype]) + "..."); | |||||
// to avoid abrupt UX | |||||
// wait for activity feedback | |||||
sleep(500).then(() => { | |||||
let res = xhiveframework.model.with_doctype(doc.doctype, () => { | |||||
let newdoc = xhiveframework.model.copy_doc(doc); | |||||
newdoc.__newname = doc.name; | |||||
delete doc.name; | |||||
newdoc.idx = null; | |||||
newdoc.__run_link_triggers = false; | |||||
xhiveframework.set_route("Form", newdoc.doctype, newdoc.name); | |||||
xhiveframework.dom.unfreeze(); | |||||
}); | |||||
res && res.fail(xhiveframework.dom.unfreeze); | |||||
}); | |||||
} | |||||
} catch (e) { | |||||
// | |||||
} | |||||
}); | |||||
} | |||||
setup_moment() { | |||||
moment.updateLocale("en", { | |||||
week: { | |||||
dow: xhiveframework.datetime.get_first_day_of_the_week_index(), | |||||
}, | |||||
}); | |||||
moment.locale("en"); | |||||
moment.user_utc_offset = moment().utcOffset(); | |||||
if (xhiveframework.boot.timezone_info) { | |||||
moment.tz.add(xhiveframework.boot.timezone_info); | |||||
} | |||||
} | |||||
}; | |||||
xhiveframework.get_module = function (m, default_module) { | |||||
var module = xhiveframework.modules[m] || default_module; | |||||
if (!module) { | |||||
return; | |||||
} | |||||
if (module._setup) { | |||||
return module; | |||||
} | |||||
if (!module.label) { | |||||
module.label = m; | |||||
} | |||||
if (!module._label) { | |||||
module._label = __(module.label); | |||||
} | |||||
module._setup = true; | |||||
return module; | |||||
}; | |||||
@@ -0,0 +1,102 @@ | |||||
import Picker from "../icon_picker/icon_picker"; | |||||
import dv_icons_list from "../icon_picker/icons_list"; | |||||
xhiveframework.ui.form.ControlIcon = class ControlIcon extends xhiveframework.ui.form.ControlData { | |||||
make_input() { | |||||
this.df.placeholder = this.df.placeholder || __("Choose an icon"); | |||||
super.make_input(); | |||||
this.make_icon_input(); | |||||
} | |||||
get_all_icons() { | |||||
xhiveframework.symbols = []; | |||||
$("#xhiveframework-symbols > symbol[id]").each(function () { | |||||
this.id.includes("icon-") && xhiveframework.symbols.push(this.id.replace("icon-", "")); | |||||
}); | |||||
} | |||||
make_icon_input() { | |||||
let picker_wrapper = $("<div>"); | |||||
this.picker = new Picker({ | |||||
parent: picker_wrapper, | |||||
icon: this.get_icon(), | |||||
icons: dv_icons_list, | |||||
}); | |||||
this.$wrapper | |||||
.popover({ | |||||
trigger: "manual", | |||||
offset: `${-this.$wrapper.width() / 4.5}, 5`, | |||||
boundary: "viewport", | |||||
placement: "bottom", | |||||
template: ` | |||||
<div class="popover icon-picker-popover"> | |||||
<div class="picker-arrow arrow"></div> | |||||
<div class="popover-body popover-content"></div> | |||||
</div> | |||||
`, | |||||
content: () => picker_wrapper, | |||||
html: true, | |||||
}) | |||||
.on("show.bs.popover", () => { | |||||
setTimeout(() => { | |||||
this.picker.refresh(); | |||||
}, 10); | |||||
}) | |||||
.on("hidden.bs.popover", () => { | |||||
$("body").off("click.icon-popover"); | |||||
$(window).off("hashchange.icon-popover"); | |||||
}); | |||||
this.picker.on_change = (icon) => { | |||||
this.set_value(icon); | |||||
}; | |||||
if (!this.selected_icon) { | |||||
this.selected_icon = $( | |||||
`<div class="selected-icon"></div>` | |||||
); | |||||
this.selected_icon.html('<i class="fal fa-folder"></i>'); | |||||
this.selected_icon.insertAfter(this.$input); | |||||
} | |||||
this.$wrapper | |||||
.find(".selected-icon") | |||||
.parent() | |||||
.on("click", (e) => { | |||||
this.$wrapper.popover("toggle"); | |||||
if (!this.get_icon()) { | |||||
this.$input.val(""); | |||||
} | |||||
e.stopPropagation(); | |||||
$("body").on("click.icon-popover", (ev) => { | |||||
if (!$(ev.target).parents().is(".popover")) { | |||||
this.$wrapper.popover("hide"); | |||||
} | |||||
}); | |||||
$(document).on("hashchange.icon-popover", () => { | |||||
this.$wrapper.popover("hide"); | |||||
}); | |||||
}); | |||||
} | |||||
refresh() { | |||||
super.refresh(); | |||||
let icon = this.get_icon(); | |||||
if (this.picker && this.picker.icon !== icon) { | |||||
this.picker.icon = icon; | |||||
this.picker.refresh(); | |||||
} | |||||
} | |||||
set_formatted_input(value) { | |||||
super.set_formatted_input(value); | |||||
this.$input.val(value); | |||||
this.selected_icon.html(`<i class="${value || 'fal fa-folder'}"></i>`); | |||||
this.selected_icon.toggleClass("no-value", !value); | |||||
} | |||||
get_icon() { | |||||
return this.get_value() || 'fal fa-folder'; | |||||
} | |||||
}; |
@@ -0,0 +1,89 @@ | |||||
class Picker { | |||||
constructor(opts) { | |||||
this.parent = opts.parent; | |||||
this.width = opts.width; | |||||
this.height = opts.height; | |||||
this.set_icon(opts.icon); | |||||
this.icons = opts.icons; | |||||
this.setup_picker(); | |||||
} | |||||
refresh() { | |||||
this.update_icon_selected(true); | |||||
} | |||||
setup_picker() { | |||||
this.icon_picker_wrapper = $(` | |||||
<div class="icon-picker"> | |||||
<div class="search-icons"> | |||||
<input type="search" placeholder="Search for icons.." class="form-control"> | |||||
<span class="search-icon">${xhiveframework.utils.icon("search", "sm")}</span> | |||||
</div> | |||||
<div class="icon-section"> | |||||
<div class="icons"></div> | |||||
</div> | |||||
</div> | |||||
`); | |||||
this.parent.append(this.icon_picker_wrapper); | |||||
this.icon_wrapper = this.icon_picker_wrapper.find(".icons"); | |||||
this.search_input = this.icon_picker_wrapper.find(".search-icons > input"); | |||||
this.refresh(); | |||||
this.setup_icons(); | |||||
} | |||||
setup_icons() { | |||||
this.icons.forEach((icon) => { | |||||
let $icon = $( | |||||
`<div id="${icon.replace('fad fa-', '')}" class="icon-wrapper"><i class="${icon}"></i></div>` | |||||
); | |||||
this.icon_wrapper.append($icon); | |||||
const set_values = () => { | |||||
this.set_icon(icon); | |||||
this.update_icon_selected(); | |||||
}; | |||||
$icon.on("click", () => { | |||||
set_values(); | |||||
}); | |||||
$icon.keydown((e) => { | |||||
const key_code = e.keyCode; | |||||
if ([13, 32].includes(key_code)) { | |||||
e.preventDefault(); | |||||
set_values(); | |||||
} | |||||
}); | |||||
}); | |||||
this.search_input.keyup((e) => { | |||||
e.preventDefault(); | |||||
this.filter_icons(); | |||||
}); | |||||
this.search_input.on("search", () => { | |||||
this.filter_icons(); | |||||
}); | |||||
} | |||||
filter_icons() { | |||||
let value = this.search_input.val(); | |||||
console.log('filter_icons-value', value) | |||||
if (!value) { | |||||
this.icon_wrapper.find(".icon-wrapper").removeClass("hidden"); | |||||
} else { | |||||
this.icon_wrapper.find(".icon-wrapper").addClass("hidden"); | |||||
this.icon_wrapper.find(`.icon-wrapper[id*='${value}']`).removeClass("hidden"); | |||||
} | |||||
} | |||||
update_icon_selected(silent) { | |||||
!silent && this.on_change && this.on_change(this.get_icon()); | |||||
} | |||||
set_icon(icon) { | |||||
this.icon = icon || ""; | |||||
} | |||||
get_icon() { | |||||
return this.icon || ""; | |||||
} | |||||
} | |||||
export default Picker; |
@@ -0,0 +1,795 @@ | |||||
const dv_icons_list = [ | |||||
"fal fa-address-book", | |||||
"fal fa-address-card", | |||||
"fal fa-adjust", | |||||
"fal fa-alarm-clock", | |||||
"fal fa-align-center", | |||||
"fal fa-align-justify", | |||||
"fal fa-align-left", | |||||
"fal fa-align-right", | |||||
"fal fa-allergies", | |||||
"fal fa-ambulance", | |||||
"fal fa-american-sign-language-interpreting", | |||||
"fal fa-anchor", | |||||
"fal fa-angle-double-down", | |||||
"fal fa-angle-double-left", | |||||
"fal fa-angle-double-right", | |||||
"fal fa-angle-double-up", | |||||
"fal fa-angle-down", | |||||
"fal fa-angle-left", | |||||
"fal fa-angle-right", | |||||
"fal fa-angle-up", | |||||
"fal fa-archive", | |||||
"fal fa-arrow-alt-circle-down", | |||||
"fal fa-arrow-alt-circle-left", | |||||
"fal fa-arrow-alt-circle-right", | |||||
"fal fa-arrow-alt-circle-up", | |||||
"fal fa-arrow-alt-down", | |||||
"fal fa-arrow-alt-from-bottom", | |||||
"fal fa-arrow-alt-from-left", | |||||
"fal fa-arrow-alt-from-right", | |||||
"fal fa-arrow-alt-from-top", | |||||
"fal fa-arrow-alt-left", | |||||
"fal fa-arrow-alt-right", | |||||
"fal fa-arrow-alt-square-down", | |||||
"fal fa-arrow-alt-square-left", | |||||
"fal fa-arrow-alt-square-right", | |||||
"fal fa-arrow-alt-square-up", | |||||
"fal fa-arrow-alt-to-bottom", | |||||
"fal fa-arrow-alt-to-left", | |||||
"fal fa-arrow-alt-to-right", | |||||
"fal fa-arrow-alt-to-top", | |||||
"fal fa-arrow-alt-up", | |||||
"fal fa-arrow-circle-down", | |||||
"fal fa-arrow-circle-left", | |||||
"fal fa-arrow-circle-right", | |||||
"fal fa-arrow-circle-up", | |||||
"fal fa-arrow-down", | |||||
"fal fa-arrow-from-bottom", | |||||
"fal fa-arrow-from-left", | |||||
"fal fa-arrow-from-right", | |||||
"fal fa-arrow-from-top", | |||||
"fal fa-arrow-left", | |||||
"fal fa-arrow-right", | |||||
"fal fa-arrow-square-down", | |||||
"fal fa-arrow-square-left", | |||||
"fal fa-arrow-square-right", | |||||
"fal fa-arrow-square-up", | |||||
"fal fa-arrow-to-bottom", | |||||
"fal fa-arrow-to-left", | |||||
"fal fa-arrow-to-right", | |||||
"fal fa-arrow-to-top", | |||||
"fal fa-arrow-up", | |||||
"fal fa-arrows", | |||||
"fal fa-arrows-alt", | |||||
"fal fa-arrows-alt-h", | |||||
"fal fa-arrows-alt-v", | |||||
"fal fa-arrows-h", | |||||
"fal fa-arrows-v", | |||||
"fal fa-assistive-listening-systems", | |||||
"fal fa-asterisk", | |||||
"fal fa-at", | |||||
"fal fa-audio-description", | |||||
"fal fa-backward", | |||||
"fal fa-badge", | |||||
"fal fa-badge-check", | |||||
"fal fa-balance-scale", | |||||
"fal fa-ban", | |||||
"fal fa-band-aid", | |||||
"fal fa-barcode", | |||||
"fal fa-barcode-alt", | |||||
"fal fa-barcode-read", | |||||
"fal fa-barcode-scan", | |||||
"fal fa-bars", | |||||
"fal fa-baseball", | |||||
"fal fa-baseball-ball", | |||||
"fal fa-basketball-ball", | |||||
"fal fa-basketball-hoop", | |||||
"fal fa-bath", | |||||
"fal fa-battery-bolt", | |||||
"fal fa-battery-empty", | |||||
"fal fa-battery-full", | |||||
"fal fa-battery-half", | |||||
"fal fa-battery-quarter", | |||||
"fal fa-battery-slash", | |||||
"fal fa-battery-three-quarters", | |||||
"fal fa-bed", | |||||
"fal fa-beer", | |||||
"fal fa-bell", | |||||
"fal fa-bell-slash", | |||||
"fal fa-bicycle", | |||||
"fal fa-binoculars", | |||||
"fal fa-birthday-cake", | |||||
"fal fa-blanket", | |||||
"fal fa-blind", | |||||
"fal fa-bold", | |||||
"fal fa-bolt", | |||||
"fal fa-bomb", | |||||
"fal fa-book", | |||||
"fal fa-book-heart", | |||||
"fal fa-bookmark", | |||||
"fal fa-bowling-ball", | |||||
"fal fa-bowling-pins", | |||||
"fal fa-box", | |||||
"fal fa-box-alt", | |||||
"fal fa-box-check", | |||||
"fal fa-box-fragile", | |||||
"fal fa-box-full", | |||||
"fal fa-box-heart", | |||||
"fal fa-box-open", | |||||
"fal fa-box-up", | |||||
"fal fa-box-usd", | |||||
"fal fa-boxes", | |||||
"fal fa-boxes-alt", | |||||
"fal fa-boxing-glove", | |||||
"fal fa-braille", | |||||
"fal fa-briefcase", | |||||
"fal fa-briefcase-medical", | |||||
"fal fa-browser", | |||||
"fal fa-bug", | |||||
"fal fa-building", | |||||
"fal fa-bullhorn", | |||||
"fal fa-bullseye", | |||||
"fal fa-burn", | |||||
"fal fa-bus", | |||||
"fal fa-calculator", | |||||
"fal fa-calendar", | |||||
"fal fa-calendar-alt", | |||||
"fal fa-calendar-check", | |||||
"fal fa-calendar-edit", | |||||
"fal fa-calendar-exclamation", | |||||
"fal fa-calendar-minus", | |||||
"fal fa-calendar-plus", | |||||
"fal fa-calendar-times", | |||||
"fal fa-camera", | |||||
"fal fa-camera-alt", | |||||
"fal fa-camera-retro", | |||||
"fal fa-capsules", | |||||
"fal fa-car", | |||||
"fal fa-caret-circle-down", | |||||
"fal fa-caret-circle-left", | |||||
"fal fa-caret-circle-right", | |||||
"fal fa-caret-circle-up", | |||||
"fal fa-caret-down", | |||||
"fal fa-caret-left", | |||||
"fal fa-caret-right", | |||||
"fal fa-caret-square-down", | |||||
"fal fa-caret-square-left", | |||||
"fal fa-caret-square-right", | |||||
"fal fa-caret-square-up", | |||||
"fal fa-caret-up", | |||||
"fal fa-cart-arrow-down", | |||||
"fal fa-cart-plus", | |||||
"fal fa-certificate", | |||||
"fal fa-chart-area", | |||||
"fal fa-chart-bar", | |||||
"fal fa-chart-line", | |||||
"fal fa-chart-pie", | |||||
"fal fa-check", | |||||
"fal fa-check-circle", | |||||
"fal fa-check-square", | |||||
"fal fa-chess", | |||||
"fal fa-chess-bishop", | |||||
"fal fa-chess-bishop-alt", | |||||
"fal fa-chess-board", | |||||
"fal fa-chess-clock", | |||||
"fal fa-chess-clock-alt", | |||||
"fal fa-chess-king", | |||||
"fal fa-chess-king-alt", | |||||
"fal fa-chess-knight", | |||||
"fal fa-chess-knight-alt", | |||||
"fal fa-chess-pawn", | |||||
"fal fa-chess-pawn-alt", | |||||
"fal fa-chess-queen", | |||||
"fal fa-chess-queen-alt", | |||||
"fal fa-chess-rook", | |||||
"fal fa-chess-rook-alt", | |||||
"fal fa-chevron-circle-down", | |||||
"fal fa-chevron-circle-left", | |||||
"fal fa-chevron-circle-right", | |||||
"fal fa-chevron-circle-up", | |||||
"fal fa-chevron-double-down", | |||||
"fal fa-chevron-double-left", | |||||
"fal fa-chevron-double-right", | |||||
"fal fa-chevron-double-up", | |||||
"fal fa-chevron-down", | |||||
"fal fa-chevron-left", | |||||
"fal fa-chevron-right", | |||||
"fal fa-chevron-square-down", | |||||
"fal fa-chevron-square-left", | |||||
"fal fa-chevron-square-right", | |||||
"fal fa-chevron-square-up", | |||||
"fal fa-chevron-up", | |||||
"fal fa-child", | |||||
"fal fa-circle", | |||||
"fal fa-circle-notch", | |||||
"fal fa-clipboard", | |||||
"fal fa-clipboard-check", | |||||
"fal fa-clipboard-list", | |||||
"fal fa-clock", | |||||
"fal fa-clone", | |||||
"fal fa-closed-captioning", | |||||
"fal fa-cloud", | |||||
"fal fa-cloud-download", | |||||
"fal fa-cloud-download-alt", | |||||
"fal fa-cloud-upload", | |||||
"fal fa-cloud-upload-alt", | |||||
"fal fa-club", | |||||
"fal fa-code", | |||||
"fal fa-code-branch", | |||||
"fal fa-code-commit", | |||||
"fal fa-code-merge", | |||||
"fal fa-coffee", | |||||
"fal fa-cog", | |||||
"fal fa-cogs", | |||||
"fal fa-columns", | |||||
"fal fa-comment", | |||||
"fal fa-comment-alt", | |||||
"fal fa-comment-alt-check", | |||||
"fal fa-comment-alt-dots", | |||||
"fal fa-comment-alt-edit", | |||||
"fal fa-comment-alt-exclamation", | |||||
"fal fa-comment-alt-lines", | |||||
"fal fa-comment-alt-minus", | |||||
"fal fa-comment-alt-plus", | |||||
"fal fa-comment-alt-slash", | |||||
"fal fa-comment-alt-smile", | |||||
"fal fa-comment-alt-times", | |||||
"fal fa-comment-check", | |||||
"fal fa-comment-dots", | |||||
"fal fa-comment-edit", | |||||
"fal fa-comment-exclamation", | |||||
"fal fa-comment-lines", | |||||
"fal fa-comment-minus", | |||||
"fal fa-comment-plus", | |||||
"fal fa-comment-slash", | |||||
"fal fa-comment-smile", | |||||
"fal fa-comment-times", | |||||
"fal fa-comments", | |||||
"fal fa-comments-alt", | |||||
"fal fa-compass", | |||||
"fal fa-compress", | |||||
"fal fa-compress-alt", | |||||
"fal fa-compress-wide", | |||||
"fal fa-container-storage", | |||||
"fal fa-conveyor-belt", | |||||
"fal fa-conveyor-belt-alt", | |||||
"fal fa-copy", | |||||
"fal fa-copyright", | |||||
"fal fa-couch", | |||||
"fal fa-credit-card", | |||||
"fal fa-credit-card-blank", | |||||
"fal fa-credit-card-front", | |||||
"fal fa-cricket", | |||||
"fal fa-crop", | |||||
"fal fa-crosshairs", | |||||
"fal fa-cube", | |||||
"fal fa-cubes", | |||||
"fal fa-curling", | |||||
"fal fa-cut", | |||||
"fal fa-database", | |||||
"fal fa-deaf", | |||||
"fal fa-desktop", | |||||
"fal fa-desktop-alt", | |||||
"fal fa-diagnoses", | |||||
"fal fa-diamond", | |||||
"fal fa-dna", | |||||
"fal fa-dollar-sign", | |||||
"fal fa-dolly", | |||||
"fal fa-dolly-empty", | |||||
"fal fa-dolly-flatbed", | |||||
"fal fa-dolly-flatbed-alt", | |||||
"fal fa-dolly-flatbed-empty", | |||||
"fal fa-donate", | |||||
"fal fa-dot-circle", | |||||
"fal fa-dove", | |||||
"fal fa-download", | |||||
"fal fa-dumbbell", | |||||
"fal fa-edit", | |||||
"fal fa-eject", | |||||
"fal fa-ellipsis-h", | |||||
"fal fa-ellipsis-h-alt", | |||||
"fal fa-ellipsis-v", | |||||
"fal fa-ellipsis-v-alt", | |||||
"fal fa-envelope", | |||||
"fal fa-envelope-open", | |||||
"fal fa-envelope-square", | |||||
"fal fa-eraser", | |||||
"fal fa-euro-sign", | |||||
"fal fa-exchange", | |||||
"fal fa-exchange-alt", | |||||
"fal fa-exclamation", | |||||
"fal fa-exclamation-circle", | |||||
"fal fa-exclamation-square", | |||||
"fal fa-exclamation-triangle", | |||||
"fal fa-expand", | |||||
"fal fa-expand-alt", | |||||
"fal fa-expand-arrows", | |||||
"fal fa-expand-arrows-alt", | |||||
"fal fa-expand-wide", | |||||
"fal fa-external-link", | |||||
"fal fa-external-link-alt", | |||||
"fal fa-external-link-square", | |||||
"fal fa-external-link-square-alt", | |||||
"fal fa-eye", | |||||
"fal fa-eye-dropper", | |||||
"fal fa-eye-slash", | |||||
"fal fa-fast-backward", | |||||
"fal fa-fast-forward", | |||||
"fal fa-fax", | |||||
"fal fa-female", | |||||
"fal fa-field-hockey", | |||||
"fal fa-fighter-jet", | |||||
"fal fa-file", | |||||
"fal fa-file-alt", | |||||
"fal fa-file-archive", | |||||
"fal fa-file-audio", | |||||
"fal fa-file-check", | |||||
"fal fa-file-code", | |||||
"fal fa-file-edit", | |||||
"fal fa-file-excel", | |||||
"fal fa-file-exclamation", | |||||
"fal fa-file-image", | |||||
"fal fa-file-medical", | |||||
"fal fa-file-medical-alt", | |||||
"fal fa-file-minus", | |||||
"fal fa-file-pdf", | |||||
"fal fa-file-plus", | |||||
"fal fa-file-powerpoint", | |||||
"fal fa-file-times", | |||||
"fal fa-file-video", | |||||
"fal fa-file-word", | |||||
"fal fa-film", | |||||
"fal fa-film-alt", | |||||
"fal fa-filter", | |||||
"fal fa-fire", | |||||
"fal fa-fire-extinguisher", | |||||
"fal fa-first-aid", | |||||
"fal fa-flag", | |||||
"fal fa-flag-checkered", | |||||
"fal fa-flask", | |||||
"fal fa-folder", | |||||
"fal fa-folder-open", | |||||
"fal fa-font", | |||||
"fal fa-football-ball", | |||||
"fal fa-football-helmet", | |||||
"fal fa-forklift", | |||||
"fal fa-forward", | |||||
"fal fa-fragile", | |||||
"fal fa-frown", | |||||
"fal fa-futbol", | |||||
"fal fa-gamepad", | |||||
"fal fa-gavel", | |||||
"fal fa-gem", | |||||
"fal fa-genderless", | |||||
"fal fa-gift", | |||||
"fal fa-glass-martini", | |||||
"fal fa-globe", | |||||
"fal fa-golf-ball", | |||||
"fal fa-golf-club", | |||||
"fal fa-graduation-cap", | |||||
"fal fa-h-square", | |||||
"fal fa-h1", | |||||
"fal fa-h2", | |||||
"fal fa-h3", | |||||
"fal fa-hand-heart", | |||||
"fal fa-hand-holding", | |||||
"fal fa-hand-holding-box", | |||||
"fal fa-hand-holding-heart", | |||||
"fal fa-hand-holding-seedling", | |||||
"fal fa-hand-holding-usd", | |||||
"fal fa-hand-holding-water", | |||||
"fal fa-hand-lizard", | |||||
"fal fa-hand-paper", | |||||
"fal fa-hand-peace", | |||||
"fal fa-hand-point-down", | |||||
"fal fa-hand-point-left", | |||||
"fal fa-hand-point-right", | |||||
"fal fa-hand-point-up", | |||||
"fal fa-hand-pointer", | |||||
"fal fa-hand-receiving", | |||||
"fal fa-hand-rock", | |||||
"fal fa-hand-scissors", | |||||
"fal fa-hand-spock", | |||||
"fal fa-hands", | |||||
"fal fa-hands-heart", | |||||
"fal fa-hands-helping", | |||||
"fal fa-hands-usd", | |||||
"fal fa-handshake", | |||||
"fal fa-handshake-alt", | |||||
"fal fa-hashtag", | |||||
"fal fa-hdd", | |||||
"fal fa-heading", | |||||
"fal fa-headphones", | |||||
"fal fa-heart", | |||||
"fal fa-heart-circle", | |||||
"fal fa-heart-square", | |||||
"fal fa-heartbeat", | |||||
"fal fa-hexagon", | |||||
"fal fa-history", | |||||
"fal fa-hockey-puck", | |||||
"fal fa-hockey-sticks", | |||||
"fal fa-home", | |||||
"fal fa-home-heart", | |||||
"fal fa-hospital", | |||||
"fal fa-hospital-alt", | |||||
"fal fa-hospital-symbol", | |||||
"fal fa-hourglass", | |||||
"fal fa-hourglass-end", | |||||
"fal fa-hourglass-half", | |||||
"fal fa-hourglass-start", | |||||
"fal fa-i-cursor", | |||||
"fal fa-id-badge", | |||||
"fal fa-id-card", | |||||
"fal fa-id-card-alt", | |||||
"fal fa-image", | |||||
"fal fa-images", | |||||
"fal fa-inbox", | |||||
"fal fa-inbox-in", | |||||
"fal fa-inbox-out", | |||||
"fal fa-indent", | |||||
"fal fa-industry", | |||||
"fal fa-industry-alt", | |||||
"fal fa-info", | |||||
"fal fa-info-circle", | |||||
"fal fa-info-square", | |||||
"fal fa-inventory", | |||||
"fal fa-italic", | |||||
"fal fa-jack-o-lantern", | |||||
"fal fa-key", | |||||
"fal fa-keyboard", | |||||
"fal fa-lamp", | |||||
"fal fa-language", | |||||
"fal fa-laptop", | |||||
"fal fa-leaf", | |||||
"fal fa-leaf-heart", | |||||
"fal fa-lemon", | |||||
"fal fa-level-down", | |||||
"fal fa-level-down-alt", | |||||
"fal fa-level-up", | |||||
"fal fa-level-up-alt", | |||||
"fal fa-life-ring", | |||||
"fal fa-lightbulb", | |||||
"fal fa-link", | |||||
"fal fa-lira-sign", | |||||
"fal fa-list", | |||||
"fal fa-list-alt", | |||||
"fal fa-list-ol", | |||||
"fal fa-list-ul", | |||||
"fal fa-location-arrow", | |||||
"fal fa-lock", | |||||
"fal fa-lock-alt", | |||||
"fal fa-lock-open", | |||||
"fal fa-lock-open-alt", | |||||
"fal fa-long-arrow-alt-down", | |||||
"fal fa-long-arrow-alt-left", | |||||
"fal fa-long-arrow-alt-right", | |||||
"fal fa-long-arrow-alt-up", | |||||
"fal fa-long-arrow-down", | |||||
"fal fa-long-arrow-left", | |||||
"fal fa-long-arrow-right", | |||||
"fal fa-long-arrow-up", | |||||
"fal fa-loveseat", | |||||
"fal fa-low-vision", | |||||
"fal fa-luchador", | |||||
"fal fa-magic", | |||||
"fal fa-magnet", | |||||
"fal fa-male", | |||||
"fal fa-map", | |||||
"fal fa-map-marker", | |||||
"fal fa-map-marker-alt", | |||||
"fal fa-map-pin", | |||||
"fal fa-map-signs", | |||||
"fal fa-mars", | |||||
"fal fa-mars-double", | |||||
"fal fa-mars-stroke", | |||||
"fal fa-mars-stroke-h", | |||||
"fal fa-mars-stroke-v", | |||||
"fal fa-medkit", | |||||
"fal fa-meh", | |||||
"fal fa-mercury", | |||||
"fal fa-microchip", | |||||
"fal fa-microphone", | |||||
"fal fa-microphone-alt", | |||||
"fal fa-microphone-slash", | |||||
"fal fa-minus", | |||||
"fal fa-minus-circle", | |||||
"fal fa-minus-hexagon", | |||||
"fal fa-minus-octagon", | |||||
"fal fa-minus-square", | |||||
"fal fa-mobile", | |||||
"fal fa-mobile-alt", | |||||
"fal fa-mobile-android", | |||||
"fal fa-mobile-android-alt", | |||||
"fal fa-money-bill", | |||||
"fal fa-money-bill-alt", | |||||
"fal fa-moon", | |||||
"fal fa-motorcycle", | |||||
"fal fa-mouse-pointer", | |||||
"fal fa-music", | |||||
"fal fa-neuter", | |||||
"fal fa-newspaper", | |||||
"fal fa-notes-medical", | |||||
"fal fa-object-group", | |||||
"fal fa-object-ungroup", | |||||
"fal fa-octagon", | |||||
"fal fa-outdent", | |||||
"fal fa-paint-brush", | |||||
"fal fa-pallet", | |||||
"fal fa-pallet-alt", | |||||
"fal fa-paper-plane", | |||||
"fal fa-paperclip", | |||||
"fal fa-parachute-box", | |||||
"fal fa-paragraph", | |||||
"fal fa-paste", | |||||
"fal fa-pause", | |||||
"fal fa-pause-circle", | |||||
"fal fa-paw", | |||||
"fal fa-pen", | |||||
"fal fa-pen-alt", | |||||
"fal fa-pen-square", | |||||
"fal fa-pencil", | |||||
"fal fa-pencil-alt", | |||||
"fal fa-pennant", | |||||
"fal fa-people-carry", | |||||
"fal fa-percent", | |||||
"fal fa-person-carry", | |||||
"fal fa-person-dolly", | |||||
"fal fa-person-dolly-empty", | |||||
"fal fa-phone", | |||||
"fal fa-phone-plus", | |||||
"fal fa-phone-slash", | |||||
"fal fa-phone-square", | |||||
"fal fa-phone-volume", | |||||
"fal fa-piggy-bank", | |||||
"fal fa-pills", | |||||
"fal fa-plane", | |||||
"fal fa-plane-alt", | |||||
"fal fa-play", | |||||
"fal fa-layer-group", | |||||
"fal fa-play-circle", | |||||
"fal fa-plug", | |||||
"fal fa-plus", | |||||
"fal fa-plus-circle", | |||||
"fal fa-plus-hexagon", | |||||
"fal fa-plus-octagon", | |||||
"fal fa-plus-square", | |||||
"fal fa-podcast", | |||||
"fal fa-poo", | |||||
"fal fa-portrait", | |||||
"fal fa-pound-sign", | |||||
"fal fa-power-off", | |||||
"fal fa-prescription-bottle", | |||||
"fal fa-prescription-bottle-alt", | |||||
"fal fa-print", | |||||
"fal fa-procedures", | |||||
"fal fa-puzzle-piece", | |||||
"fal fa-qrcode", | |||||
"fal fa-question", | |||||
"fal fa-question-circle", | |||||
"fal fa-question-square", | |||||
"fal fa-quidditch", | |||||
"fal fa-quote-left", | |||||
"fal fa-quote-right", | |||||
"fal fa-racquet", | |||||
"fal fa-ramp-loading", | |||||
"fal fa-random", | |||||
"fal fa-rectangle-landscape", | |||||
"fal fa-rectangle-portrait", | |||||
"fal fa-rectangle-wide", | |||||
"fal fa-recycle", | |||||
"fal fa-redo", | |||||
"fal fa-redo-alt", | |||||
"fal fa-registered", | |||||
"fal fa-repeat", | |||||
"fal fa-repeat-1", | |||||
"fal fa-repeat-1-alt", | |||||
"fal fa-repeat-alt", | |||||
"fal fa-reply", | |||||
"fal fa-reply-all", | |||||
"fal fa-retweet", | |||||
"fal fa-retweet-alt", | |||||
"fal fa-ribbon", | |||||
"fal fa-road", | |||||
"fal fa-rocket", | |||||
"fal fa-route", | |||||
"fal fa-rss", | |||||
"fal fa-rss-square", | |||||
"fal fa-ruble-sign", | |||||
"fal fa-rupee-sign", | |||||
"fal fa-save", | |||||
"fal fa-scanner", | |||||
"fal fa-scanner-keyboard", | |||||
"fal fa-scanner-touchscreen", | |||||
"fal fa-scrubber", | |||||
"fal fa-search", | |||||
"fal fa-search-minus", | |||||
"fal fa-search-plus", | |||||
"fal fa-seedling", | |||||
"fal fa-server", | |||||
"fal fa-share", | |||||
"fal fa-share-all", | |||||
"fal fa-share-alt", | |||||
"fal fa-share-alt-square", | |||||
"fal fa-share-square", | |||||
"fal fa-shekel-sign", | |||||
"fal fa-shield", | |||||
"fal fa-shield-alt", | |||||
"fal fa-shield-check", | |||||
"fal fa-ship", | |||||
"fal fa-shipping-fast", | |||||
"fal fa-shipping-timed", | |||||
"fal fa-shopping-bag", | |||||
"fal fa-shopping-basket", | |||||
"fal fa-shopping-cart", | |||||
"fal fa-shower", | |||||
"fal fa-shuttlecock", | |||||
"fal fa-sign", | |||||
"fal fa-sign-in", | |||||
"fal fa-sign-in-alt", | |||||
"fal fa-sign-language", | |||||
"fal fa-sign-out", | |||||
"fal fa-sign-out-alt", | |||||
"fal fa-signal", | |||||
"fal fa-sitemap", | |||||
"fal fa-sliders-h", | |||||
"fal fa-sliders-h-square", | |||||
"fal fa-sliders-v", | |||||
"fal fa-sliders-v-square", | |||||
"fal fa-smile", | |||||
"fal fa-smile-plus", | |||||
"fal fa-smoking", | |||||
"fal fa-snowflake", | |||||
"fal fa-sort", | |||||
"fal fa-sort-alpha-down", | |||||
"fal fa-sort-alpha-up", | |||||
"fal fa-sort-amount-down", | |||||
"fal fa-sort-amount-up", | |||||
"fal fa-sort-down", | |||||
"fal fa-sort-numeric-down", | |||||
"fal fa-sort-numeric-up", | |||||
"fal fa-sort-up", | |||||
"fal fa-space-shuttle", | |||||
"fal fa-spade", | |||||
"fal fa-spinner", | |||||
"fal fa-spinner-third", | |||||
"fal fa-square", | |||||
"fal fa-square-full", | |||||
"fal fa-star", | |||||
"fal fa-star-exclamation", | |||||
"fal fa-star-half", | |||||
"fal fa-step-backward", | |||||
"fal fa-step-forward", | |||||
"fal fa-stethoscope", | |||||
"fal fa-sticky-note", | |||||
"fal fa-stop", | |||||
"fal fa-stop-circle", | |||||
"fal fa-stopwatch", | |||||
"fal fa-street-view", | |||||
"fal fa-strikethrough", | |||||
"fal fa-subscript", | |||||
"fal fa-subway", | |||||
"fal fa-suitcase", | |||||
"fal fa-sun", | |||||
"fal fa-superscript", | |||||
"fal fa-sync", | |||||
"fal fa-sync-alt", | |||||
"fal fa-syringe", | |||||
"fal fa-table", | |||||
"fal fa-table-tennis", | |||||
"fal fa-tablet", | |||||
"fal fa-tablet-alt", | |||||
"fal fa-tablet-android", | |||||
"fal fa-tablet-android-alt", | |||||
"fal fa-tablet-rugged", | |||||
"fal fa-tablets", | |||||
"fal fa-tachometer", | |||||
"fal fa-tachometer-alt", | |||||
"fal fa-tag", | |||||
"fal fa-tags", | |||||
"fal fa-tape", | |||||
"fal fa-tasks", | |||||
"fal fa-taxi", | |||||
"fal fa-tennis-ball", | |||||
"fal fa-terminal", | |||||
"fal fa-text-height", | |||||
"fal fa-text-width", | |||||
"fal fa-th", | |||||
"fal fa-th-large", | |||||
"fal fa-th-list", | |||||
"fal fa-thermometer", | |||||
"fal fa-thermometer-empty", | |||||
"fal fa-thermometer-full", | |||||
"fal fa-thermometer-half", | |||||
"fal fa-thermometer-quarter", | |||||
"fal fa-thermometer-three-quarters", | |||||
"fal fa-thumbs-down", | |||||
"fal fa-thumbs-up", | |||||
"fal fa-thumbtack", | |||||
"fal fa-ticket", | |||||
"fal fa-ticket-alt", | |||||
"fal fa-times", | |||||
"fal fa-times-circle", | |||||
"fal fa-times-hexagon", | |||||
"fal fa-times-octagon", | |||||
"fal fa-times-square", | |||||
"fal fa-tint", | |||||
"fal fa-toggle-off", | |||||
"fal fa-toggle-on", | |||||
"fal fa-trademark", | |||||
"fal fa-train", | |||||
"fal fa-transgender", | |||||
"fal fa-transgender-alt", | |||||
"fal fa-trash", | |||||
"fal fa-trash-alt", | |||||
"fal fa-tree", | |||||
"fal fa-tree-alt", | |||||
"fal fa-triangle", | |||||
"fal fa-trophy", | |||||
"fal fa-trophy-alt", | |||||
"fal fa-truck", | |||||
"fal fa-truck-container", | |||||
"fal fa-truck-couch", | |||||
"fal fa-truck-loading", | |||||
"fal fa-truck-moving", | |||||
"fal fa-truck-ramp", | |||||
"fal fa-tty", | |||||
"fal fa-tv", | |||||
"fal fa-tv-retro", | |||||
"fal fa-umbrella", | |||||
"fal fa-underline", | |||||
"fal fa-undo", | |||||
"fal fa-undo-alt", | |||||
"fal fa-universal-access", | |||||
"fal fa-university", | |||||
"fal fa-unlink", | |||||
"fal fa-unlock", | |||||
"fal fa-unlock-alt", | |||||
"fal fa-upload", | |||||
"fal fa-usd-circle", | |||||
"fal fa-usd-square", | |||||
"fal fa-user", | |||||
"fal fa-user-alt", | |||||
"fal fa-user-circle", | |||||
"fal fa-user-md", | |||||
"fal fa-user-plus", | |||||
"fal fa-user-secret", | |||||
"fal fa-user-times", | |||||
"fal fa-users", | |||||
"fal fa-utensil-fork", | |||||
"fal fa-utensil-knife", | |||||
"fal fa-utensil-spoon", | |||||
"fal fa-utensils", | |||||
"fal fa-utensils-alt", | |||||
"fal fa-venus", | |||||
"fal fa-venus-double", | |||||
"fal fa-venus-mars", | |||||
"fal fa-vial", | |||||
"fal fa-vials", | |||||
"fal fa-video", | |||||
"fal fa-video-plus", | |||||
"fal fa-video-slash", | |||||
"fal fa-volleyball-ball", | |||||
"fal fa-volume-down", | |||||
"fal fa-volume-mute", | |||||
"fal fa-volume-off", | |||||
"fal fa-volume-up", | |||||
"fal fa-warehouse", | |||||
"fal fa-warehouse-alt", | |||||
"fal fa-watch", | |||||
"fal fa-weight", | |||||
"fal fa-wheelchair", | |||||
"fal fa-whistle", | |||||
"fal fa-wifi", | |||||
"fal fa-window", | |||||
"fal fa-window-alt", | |||||
"fal fa-window-close", | |||||
"fal fa-window-maximize", | |||||
"fal fa-window-minimize", | |||||
"fal fa-window-restore", | |||||
"fal fa-wine-glass", | |||||
"fal fa-won-sign", | |||||
"fal fa-wrench", | |||||
"fal fa-x-ray" | |||||
]; | |||||
export default dv_icons_list; |
@@ -0,0 +1,443 @@ | |||||
xhiveframework.provide('xhiveframework.search'); | |||||
xhiveframework.ui.Notifications = class Notifications { | |||||
constructor() { | |||||
this.tabs = {}; | |||||
this.notification_settings = xhiveframework.boot.notification_settings; | |||||
this.make(); | |||||
} | |||||
make() { | |||||
this.dropdown = $('.dv-navbar.datavalue-nav').find('.dv-dropdown-notifications').removeClass('hidden'); | |||||
this.dropdown_list = this.dropdown.find('.notifications-list'); | |||||
this.header_items = this.dropdown_list.find('.header-items').html(''); | |||||
this.header_actions = this.dropdown_list.find('.header-actions').html(''); | |||||
this.body = this.dropdown_list.find('.notification-list-body'); | |||||
this.panel_events = this.dropdown_list.find('.panel-events'); | |||||
this.panel_notifications = this.dropdown_list.find('.panel-notifications'); | |||||
this.user = xhiveframework.session.user; | |||||
this.setup_headers(); | |||||
this.setup_dropdown_events(); | |||||
} | |||||
setup_headers() { | |||||
// Add header actions | |||||
$(`<span class="notification-settings pull-right" data-action="go_to_settings"> | |||||
${xhiveframework.utils.icon('setting-gear')} | |||||
</span>`) | |||||
.on('click', (e) => { | |||||
e.stopImmediatePropagation(); | |||||
this.dropdown.dropdown('hide'); | |||||
xhiveframework.set_route('Form', 'Notification Settings', xhiveframework.session.user); | |||||
}).appendTo(this.header_actions) | |||||
.attr('title', __("Notification Settings")) | |||||
.tooltip({delay: {"show": 600, "hide": 100}, trigger: "hover"}); | |||||
$(`<span class="mark-all-read pull-right" data-action="mark_all_as_read"> | |||||
${xhiveframework.utils.icon('mark-as-read')} | |||||
</span>`) | |||||
.on('click', (e) => this.mark_all_as_read(e)) | |||||
.appendTo(this.header_actions) | |||||
.attr('title', __("Mark all as read")) | |||||
.tooltip({delay: {"show": 600, "hide": 100}, trigger: "hover"}); | |||||
this.categories = [ | |||||
{ | |||||
label: __("Notifications"), | |||||
id: "notifications", | |||||
view: NotificationsView, | |||||
el: this.panel_notifications, | |||||
}, | |||||
{ | |||||
label: __("Today's Events"), | |||||
id: "todays_events", | |||||
view: EventsView, | |||||
el: this.panel_events, | |||||
} | |||||
]; | |||||
let get_headers_html = (item) => { | |||||
let active = item.id == "notifications" ? 'active' : ''; | |||||
let html = `<li class="notifications-category ${active}" | |||||
id="${item.id}" | |||||
data-toggle="collapse" | |||||
>${item.label}</li>`; | |||||
return html; | |||||
}; | |||||
let navitem = $(`<ul class="notification-item-tabs nav nav-tabs" role="tablist"></ul>`); | |||||
this.categories = this.categories.map(item => { | |||||
item.$tab = $(get_headers_html(item)); | |||||
item.$tab.on('click', (e) => { | |||||
e.stopImmediatePropagation(); | |||||
this.switch_tab(item); | |||||
}); | |||||
navitem.append(item.$tab); | |||||
return item; | |||||
}); | |||||
navitem.appendTo(this.header_items); | |||||
this.categories.forEach(category => { | |||||
this.make_tab_view(category); | |||||
}); | |||||
this.switch_tab(this.categories[0]); | |||||
} | |||||
switch_tab(item) { | |||||
// Set active tab | |||||
this.categories.forEach((item) => { | |||||
item.$tab.removeClass("active"); | |||||
}); | |||||
item.$tab.addClass("active"); | |||||
// Hide other tabs | |||||
Object.keys(this.tabs).forEach(tab_name => this.tabs[tab_name].hide()); | |||||
this.tabs[item.id].show(); | |||||
} | |||||
make_tab_view(item) { | |||||
let tabView = new item.view( | |||||
item.el, | |||||
this.dropdown, | |||||
this.notification_settings | |||||
); | |||||
this.tabs[item.id] = tabView; | |||||
} | |||||
mark_all_as_read(e) { | |||||
e.stopImmediatePropagation(); | |||||
this.dropdown_list.find('.unread').removeClass('unread'); | |||||
xhiveframework.call( | |||||
'xhiveframework.desk.doctype.notification_log.notification_log.mark_all_as_read', | |||||
); | |||||
} | |||||
setup_dropdown_events() { | |||||
this.dropdown.on('hide.bs.dropdown', e => { | |||||
let hide = $(e.currentTarget).data('closable'); | |||||
$(e.currentTarget).data('closable', true); | |||||
return hide; | |||||
}); | |||||
this.dropdown.on('click', e => { | |||||
$(e.currentTarget).data('closable', true); | |||||
}); | |||||
} | |||||
}; | |||||
xhiveframework.ui.notifications = { | |||||
get_notification_config() { | |||||
return xhiveframework.xcall('xhiveframework.desk.notifications.get_notification_info').then(r => { | |||||
xhiveframework.ui.notifications.config = r; | |||||
return r; | |||||
}); | |||||
}, | |||||
show_open_count_list(doctype) { | |||||
if (!xhiveframework.ui.notifications.config) { | |||||
this.get_notification_config().then(() => { | |||||
this.route_to_list_with_filters(doctype); | |||||
}); | |||||
} else { | |||||
this.route_to_list_with_filters(doctype); | |||||
} | |||||
}, | |||||
route_to_list_with_filters(doctype) { | |||||
let filters = xhiveframework.ui.notifications.config['conditions'][doctype]; | |||||
if (filters && $.isPlainObject(filters)) { | |||||
if (!xhiveframework.route_options) { | |||||
xhiveframework.route_options = {}; | |||||
} | |||||
$.extend(xhiveframework.route_options, filters); | |||||
} | |||||
xhiveframework.set_route('List', doctype); | |||||
} | |||||
}; | |||||
class BaseNotificationsView { | |||||
constructor(wrapper, parent, settings) { | |||||
// wrapper, max_length | |||||
this.wrapper = wrapper; | |||||
this.parent = parent; | |||||
this.settings = settings; | |||||
this.max_length = 20; | |||||
this.wrapper.html(''); | |||||
this.container = $(`<div></div>`).appendTo(this.wrapper); | |||||
this.make(); | |||||
} | |||||
show() { | |||||
this.container.show(); | |||||
} | |||||
hide() { | |||||
this.container.hide(); | |||||
} | |||||
} | |||||
class NotificationsView extends BaseNotificationsView { | |||||
make() { | |||||
this.notifications_icon = this.parent.find('.notifications-icon'); | |||||
this.notifications_icon.attr("title", __('Notifications')).tooltip( | |||||
{delay: {"show": 600, "hide": 100}, trigger: "hover"} | |||||
); | |||||
this.setup_notification_listeners(); | |||||
this.get_notifications_list(this.max_length).then(list => { | |||||
this.dropdown_items = list; | |||||
this.render_notifications_dropdown(); | |||||
if (this.settings.seen == 0) { | |||||
this.toggle_notification_icon(false); | |||||
} | |||||
}); | |||||
} | |||||
update_dropdown() { | |||||
this.get_notifications_list(1).then(r => { | |||||
let new_item = r[0]; | |||||
this.dropdown_items.unshift(new_item); | |||||
if (this.dropdown_items.length > this.max_length) { | |||||
this.container | |||||
.find('.recent-notification') | |||||
.last() | |||||
.remove(); | |||||
this.dropdown_items.pop(); | |||||
} | |||||
this.insert_into_dropdown(); | |||||
}); | |||||
} | |||||
change_activity_status() { | |||||
if (this.container.find('.activity-status')) { | |||||
this.container.find('.activity-status').replaceWith( | |||||
`<a class="recent-item text-center text-muted" | |||||
href="/app/List/Notification Log"> | |||||
<div class="full-log-btn">${__('View Full Log')}</div> | |||||
</a>` | |||||
); | |||||
} | |||||
} | |||||
mark_as_read(docname, $el) { | |||||
xhiveframework.call( | |||||
'xhiveframework.desk.doctype.notification_log.notification_log.mark_as_read', | |||||
{docname: docname} | |||||
).then(() => { | |||||
$el.removeClass('unread'); | |||||
}); | |||||
} | |||||
insert_into_dropdown() { | |||||
let new_item = this.dropdown_items[0]; | |||||
let new_item_html = this.get_dropdown_item_html(new_item); | |||||
$(new_item_html).prependTo(this.container); | |||||
this.change_activity_status(); | |||||
} | |||||
get_dropdown_item_html(field) { | |||||
let doc_link = this.get_item_link(field); | |||||
let read_class = field.read ? '' : 'unread'; | |||||
let message = field.subject; | |||||
let title = message.match(/<b class="subject-title">(.*?)<\/b>/); | |||||
message = title ? message.replace(title[1], xhiveframework.ellipsis(strip_html(title[1]), 100)) : message; | |||||
let timestamp = xhiveframework.datetime.comment_when(field.creation); | |||||
let message_html = `<div class="message"> | |||||
<div>${message}</div> | |||||
<div class="notification-timestamp text-muted"> | |||||
${timestamp} | |||||
</div> | |||||
</div>`; | |||||
let user = field.from_user; | |||||
let user_avatar = xhiveframework.avatar(user, 'avatar-medium user-avatar'); | |||||
let item_html = | |||||
$(`<a class="recent-item notification-item ${read_class}" | |||||
href="${doc_link}" | |||||
data-name="${field.name}" | |||||
> | |||||
<div class="notification-body"> | |||||
${user_avatar} | |||||
${message_html} | |||||
</div> | |||||
<div class="mark-as-read" title="${__("Mark as Read")}"> | |||||
</div> | |||||
</a>`); | |||||
if (!field.read) { | |||||
let mark_btn = item_html.find(".mark-as-read"); | |||||
mark_btn.tooltip({delay: {"show": 600, "hide": 100}, trigger: "hover"}); | |||||
mark_btn.on('click', (e) => { | |||||
e.preventDefault(); | |||||
e.stopImmediatePropagation(); | |||||
this.mark_as_read(field.name, item_html); | |||||
}); | |||||
item_html.on('click', () => { | |||||
this.mark_as_read(field.name, item_html); | |||||
}); | |||||
} | |||||
return item_html; | |||||
} | |||||
render_notifications_dropdown() { | |||||
if (this.settings && !this.settings.enabled) { | |||||
this.container.html(`<li class="recent-item notification-item"> | |||||
<span class="text-muted"> | |||||
${__('Notifications Disabled')} | |||||
</span></li>`); | |||||
} else { | |||||
if (this.dropdown_items.length) { | |||||
this.container.empty(); | |||||
this.dropdown_items.forEach(field => { | |||||
this.container.append(this.get_dropdown_item_html(field)); | |||||
}); | |||||
this.container.append(`<a class="list-footer" | |||||
href="/app/List/Notification Log"> | |||||
<div class="full-log-btn">${__('See all Activity')}</div> | |||||
</a>`); | |||||
} else { | |||||
this.container.append($(`<div class="notification-null-state"> | |||||
<div class="text-center"> | |||||
<img src="/assets/xhiveframework/images/ui-states/notification-empty-state.svg" alt="Generic Empty State" class="null-state"> | |||||
<div class="title">${__('No New notifications')}</div> | |||||
<div class="subtitle"> | |||||
${__('Looks like you haven’t received any notifications.')} | |||||
</div></div></div>`)); | |||||
} | |||||
} | |||||
} | |||||
get_notifications_list(limit) { | |||||
return xhiveframework.db.get_list('Notification Log', { | |||||
fields: ['*'], | |||||
limit: limit, | |||||
order_by: 'creation desc' | |||||
}); | |||||
} | |||||
get_item_link(notification_doc) { | |||||
const link_doctype = | |||||
notification_doc.type == 'Alert' ? 'Notification Log' : notification_doc.document_type; | |||||
const link_docname = | |||||
notification_doc.type == 'Alert' ? notification_doc.name : notification_doc.document_name; | |||||
return xhiveframework.utils.get_form_link( | |||||
link_doctype, | |||||
link_docname | |||||
); | |||||
} | |||||
toggle_notification_icon(seen) { | |||||
this.notifications_icon.find('.notifications-seen').toggle(seen); | |||||
this.notifications_icon.find('.notifications-unseen').toggle(!seen); | |||||
} | |||||
toggle_seen(flag) { | |||||
xhiveframework.call( | |||||
'xhiveframework.desk.doctype.notification_settings.notification_settings.set_seen_value', | |||||
{ | |||||
value: cint(flag), | |||||
user: xhiveframework.session.user | |||||
} | |||||
); | |||||
} | |||||
setup_notification_listeners() { | |||||
xhiveframework.realtime.on('notification', () => { | |||||
this.toggle_notification_icon(false); | |||||
this.update_dropdown(); | |||||
}); | |||||
xhiveframework.realtime.on('indicator_hide', () => { | |||||
this.toggle_notification_icon(true); | |||||
}); | |||||
this.parent.on('show.bs.dropdown', () => { | |||||
this.toggle_seen(true); | |||||
if (this.notifications_icon.find('.notifications-unseen').is(':visible')) { | |||||
this.toggle_notification_icon(true); | |||||
xhiveframework.call( | |||||
'xhiveframework.desk.doctype.notification_log.notification_log.trigger_indicator_hide' | |||||
); | |||||
} | |||||
}); | |||||
} | |||||
} | |||||
class EventsView extends BaseNotificationsView { | |||||
make() { | |||||
let today = xhiveframework.datetime.get_today(); | |||||
xhiveframework.xcall('xhiveframework.desk.doctype.event.event.get_events', { | |||||
start: today, | |||||
end: today | |||||
}).then(event_list => { | |||||
this.render_events_html(event_list); | |||||
}); | |||||
} | |||||
render_events_html(event_list) { | |||||
let html = ''; | |||||
if (event_list.length) { | |||||
let get_event_html = (event) => { | |||||
let time = __("All Day"); | |||||
if (!event.all_day) { | |||||
let start_time = xhiveframework.datetime.get_time(event.starts_on); | |||||
let days_diff = xhiveframework.datetime.get_day_diff(event.ends_on, event.starts_on); | |||||
let end_time = xhiveframework.datetime.get_time(event.ends_on); | |||||
if (days_diff > 1) { | |||||
end_time = __("Rest of the day"); | |||||
} | |||||
time = `${start_time} - ${end_time}`; | |||||
} | |||||
// REDESIGN-TODO: Add Participants to get_events query | |||||
let particpants = ''; | |||||
if (event.particpants) { | |||||
particpants = xhiveframework.avatar_group(event.particpants, 3); | |||||
} | |||||
// REDESIGN-TODO: Add location to calendar field | |||||
let location = ''; | |||||
if (event.location) { | |||||
location = `, ${event.location}`; | |||||
} | |||||
return `<a class="recent-item event" href="/app/event/${event.name}"> | |||||
<div class="event-border" style="border-color: ${event.color}"></div> | |||||
<div class="event-item"> | |||||
<div class="event-subject">${event.subject}</div> | |||||
<div class="event-time">${time}${location}</div> | |||||
${particpants} | |||||
</div> | |||||
</a>`; | |||||
}; | |||||
html = event_list.map(get_event_html).join(''); | |||||
} else { | |||||
html = ` | |||||
<div class="notification-null-state"> | |||||
<div class="text-center"> | |||||
<img src="/assets/xhiveframework/images/ui-states/event-empty-state.svg" alt="Generic Empty State" class="null-state"> | |||||
<div class="title">${__('No Upcoming Events')}</div> | |||||
<div class="subtitle"> | |||||
${__('There are no upcoming events for you.')} | |||||
</div></div></div> | |||||
`; | |||||
} | |||||
this.container.html(html); | |||||
} | |||||
} |
@@ -0,0 +1,84 @@ | |||||
<div class="page-head flex"> | |||||
<div class="container"> | |||||
<div class="row flex align-center page-head-content justify-between"> | |||||
<div class="col-md-4 col-sm-6 col-xs-8 page-title"> | |||||
<!-- <div class="title-image hide hidden-md hidden-lg"></div> --> | |||||
<!-- title --> | |||||
<span class="sidebar-toggle-btn show-in-mobile-lg"> | |||||
<svg class="icon icon-md sidebar-toggle-placeholder"> | |||||
<use xlink:href="#icon-menu"></use> | |||||
</svg> | |||||
<span class="sidebar-toggle-icon"> | |||||
<svg class="icon icon-md"> | |||||
<use xlink:href="#icon-sidebar-collapse"> | |||||
</use> | |||||
</svg> | |||||
</span> | |||||
</span> | |||||
<button type="button" class="btn-toggle-main-menu menu-shown"><i class="far fa-bars"></i></button> | |||||
<div class="flex fill-width title-area"> | |||||
<div> | |||||
<div class="flex"> | |||||
<h3 class="ellipsis title-text"></h3> | |||||
<span class="indicator-pill whitespace-nowrap"></span> | |||||
</div> | |||||
<div class="ellipsis sub-heading hide text-muted"></div> | |||||
</div> | |||||
<button class="btn btn-default more-button hide"> | |||||
<svg class="icon icon-sm"> | |||||
<use xlink:href="#icon-dot-horizontal"> | |||||
</use> | |||||
</svg> | |||||
</button> | |||||
</div> | |||||
</div> | |||||
<div class="flex col page-actions justify-content-end"> | |||||
<!-- buttons --> | |||||
<div class="custom-actions hide hidden-xs hidden-md"></div> | |||||
<div class="standard-actions flex"> | |||||
<span class="page-icon-group hide hidden-xs hidden-sm"></span> | |||||
<div class="menu-btn-group hide"> | |||||
<button type="button" class="btn btn-default icon-btn" data-toggle="dropdown" aria-expanded="false"> | |||||
<span> | |||||
<span class="menu-btn-group-label"> | |||||
<svg class="icon icon-sm"> | |||||
<use xlink:href="#icon-dot-horizontal"> | |||||
</use> | |||||
</svg> | |||||
</span> | |||||
</span> | |||||
</button> | |||||
<ul class="dropdown-menu dropdown-menu-right" role="menu"></ul> | |||||
</div> | |||||
<button class="btn btn-secondary btn-default btn-sm hide"></button> | |||||
<div class="actions-btn-group hide"> | |||||
<button type="button" class="btn btn-primary btn-sm" data-toggle="dropdown" aria-expanded="false"> | |||||
<span class="hidden-xs"> | |||||
<span class="actions-btn-group-label">{%= __("Actions") %}</span> | |||||
<svg class="icon icon-xs"> | |||||
<use xlink:href="#icon-select"> | |||||
</use> | |||||
</svg> | |||||
</span> | |||||
</button> | |||||
<ul class="dropdown-menu dropdown-menu-right" role="menu"> | |||||
</ul> | |||||
</div> | |||||
<button class="btn btn-primary btn-sm hide primary-action"></button> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
</div> | |||||
<div class="container page-body"> | |||||
<div class="page-toolbar hide"> | |||||
<div class="container"> | |||||
</div> | |||||
</div> | |||||
<div class="page-wrapper"> | |||||
<div class="page-content"> | |||||
<div class="workflow-button-area btn-group pull-right hide"></div> | |||||
<div class="clearfix"></div> | |||||
</div> | |||||
</div> | |||||
</div> |
@@ -0,0 +1,911 @@ | |||||
// Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||||
// MIT License. See license.txt | |||||
/** | |||||
* Make a standard page layout with a toolbar and title | |||||
* | |||||
* @param {Object} opts | |||||
* | |||||
* @param {string} opts.parent [HTMLElement] Parent element | |||||
* @param {boolean} opts.single_column Whether to include sidebar | |||||
* @param {string} [opts.title] Page title | |||||
* @param {Object} [opts.make_page] | |||||
* | |||||
* @returns {xhiveframework.ui.Page} | |||||
*/ | |||||
/** | |||||
* @typedef {Object} xhiveframework.ui.Page | |||||
*/ | |||||
xhiveframework.ui.make_app_page = function (opts) { | |||||
opts.parent.page = new xhiveframework.ui.Page(opts); | |||||
return opts.parent.page; | |||||
} | |||||
xhiveframework.ui.pages = {}; | |||||
xhiveframework.ui.Page = Class.extend({ | |||||
init: function (opts) { | |||||
$.extend(this, opts); | |||||
this.set_document_title = true; | |||||
this.buttons = {}; | |||||
this.fields_dict = {}; | |||||
this.views = {}; | |||||
this.make(); | |||||
xhiveframework.ui.pages[xhiveframework.get_route_str()] = this; | |||||
}, | |||||
make: function () { | |||||
this.wrapper = $(this.parent); | |||||
this.add_main_section(); | |||||
this.setup_scroll_handler(); | |||||
this.setup_sidebar_toggle(); | |||||
}, | |||||
setup_scroll_handler() { | |||||
window.addEventListener('scroll', () => { | |||||
if (document.documentElement.scrollTop >= 60) { | |||||
$('.page-head').toggleClass('drop-shadow', true); | |||||
} else { | |||||
$('.page-head').removeClass('drop-shadow'); | |||||
} | |||||
}); | |||||
}, | |||||
get_empty_state: function (title, message, primary_action) { | |||||
let $empty_state = $(`<div class="page-card-container"> | |||||
<div class="page-card"> | |||||
<div class="page-card-head"> | |||||
<span class="indicator blue"> | |||||
${title}</span> | |||||
</div> | |||||
<p>${message}</p> | |||||
<div> | |||||
<button class="btn btn-primary btn-sm">${primary_action}</button> | |||||
</div> | |||||
</div> | |||||
</div>`); | |||||
return $empty_state; | |||||
}, | |||||
load_lib: function (callback) { | |||||
xhiveframework.require(this.required_libs, callback); | |||||
}, | |||||
add_main_section: function () { | |||||
$(xhiveframework.render_template("page", {})).appendTo(this.wrapper); | |||||
if (this.single_column) { | |||||
// nesting under col-sm-12 for consistency | |||||
this.add_view("main", `<div class="row layout-main"> | |||||
<div class="col-md-12 layout-main-section-wrapper"> | |||||
<div class="layout-main-section"></div> | |||||
<div class="layout-footer hide"></div> | |||||
</div> | |||||
</div>`); | |||||
} else { | |||||
this.add_view("main", ` | |||||
<div class="row layout-main"> | |||||
<div class="col-lg-2 layout-side-section"></div> | |||||
<div class="col layout-main-section-wrapper"> | |||||
<div class="layout-main-section"></div> | |||||
<div class="layout-footer hide"></div> | |||||
</div> | |||||
</div> | |||||
`); | |||||
} | |||||
this.setup_page(); | |||||
}, | |||||
setup_page: function () { | |||||
let $this = this; | |||||
this.$title_area = this.wrapper.find(".title-area"); | |||||
this.$sub_title_area = this.wrapper.find("h6"); | |||||
if (this.title) | |||||
this.set_title(this.title); | |||||
if (this.icon) | |||||
this.get_main_icon(this.icon); | |||||
this.body = this.main = this.wrapper.find(".layout-main-section"); | |||||
this.container = this.wrapper.find(".page-body"); | |||||
this.sidebar = this.wrapper.find(".layout-side-section"); | |||||
this.footer = this.wrapper.find(".layout-footer"); | |||||
this.indicator = this.wrapper.find(".indicator-pill"); | |||||
this.page_actions = this.wrapper.find(".page-actions"); | |||||
this.btn_primary = this.page_actions.find(".primary-action"); | |||||
this.btn_secondary = this.page_actions.find(".btn-secondary"); | |||||
this.menu = this.page_actions.find(".menu-btn-group .dropdown-menu"); | |||||
this.menu_btn_group = this.page_actions.find(".menu-btn-group"); | |||||
this.actions = this.page_actions.find(".actions-btn-group .dropdown-menu"); | |||||
this.actions_btn_group = this.page_actions.find(".actions-btn-group"); | |||||
this.standard_actions = this.page_actions.find(".standard-actions"); | |||||
this.custom_actions = this.page_actions.find(".custom-actions"); | |||||
this.page_form = $('<div class="page-form row hide"></div>').prependTo(this.main); | |||||
this.inner_toolbar = this.custom_actions; | |||||
this.icon_group = this.page_actions.find(".page-icon-group"); | |||||
if (this.make_page) { | |||||
this.make_page(); | |||||
} | |||||
this.card_layout && this.main.addClass('xhiveframework-card'); | |||||
// keyboard shortcuts | |||||
let menu_btn = this.menu_btn_group.find('button'); | |||||
menu_btn.attr("title", __("Menu")).tooltip({delay: {"show": 600, "hide": 100}}); | |||||
xhiveframework.ui.keys.get_shortcut_group(this.page_actions[0]).add(menu_btn, menu_btn.find('.menu-btn-group-label')); | |||||
let action_btn = this.actions_btn_group.find('button'); | |||||
xhiveframework.ui.keys.get_shortcut_group(this.page_actions[0]).add(action_btn, action_btn.find('.actions-btn-group-label')); | |||||
let route = xhiveframework.get_route(); | |||||
let sidebar_wrapper = this.wrapper.find('.layout-side-section'); | |||||
this.body.append('<button type="button" class="btn-toggle-sidebar sidebar-shown"><i class="far fa-angle-right"></i></button>'); | |||||
this.page_container = this.body.parents('.page-container'); | |||||
// if (this.sidebar.length) { | |||||
// console.log('Hide this.sidebar', this.sidebar) | |||||
// this.sidebar.hide(); | |||||
// } | |||||
if (route && route.length && route[0]) { | |||||
if (route[0] != 'Workspaces' && route[0] != 'query-report' && route[0] != 'Tree') { | |||||
if (xhiveframework.utils.is_xs() || xhiveframework.utils.is_sm()) { | |||||
} else { | |||||
setTimeout(() => $('.btn-toggle-sidebar', this.page_container).trigger('click'), 250); | |||||
} | |||||
$('.btn-toggle-sidebar', this.page_container).show(); | |||||
} else { | |||||
$('.btn-toggle-sidebar', this.page_container).hide(); | |||||
} | |||||
} else { | |||||
$('.btn-toggle-sidebar', this.page_container).hide(); | |||||
} | |||||
$(this.page_container).on('click', '.btn-toggle-sidebar', function () { | |||||
if ($(this).hasClass('sidebar-shown')) { | |||||
$(this).removeClass('sidebar-shown'); | |||||
} else { | |||||
$(this).addClass('sidebar-shown'); | |||||
} | |||||
if (xhiveframework.utils.is_xs() || xhiveframework.utils.is_sm()) { | |||||
$this.setup_overlay_sidebar(); | |||||
} else { | |||||
sidebar_wrapper.toggle(); | |||||
} | |||||
$(document.body).trigger('toggleSidebar'); | |||||
}); | |||||
}, | |||||
setup_sidebar_toggle() { | |||||
let sidebar_toggle = $('.page-head').find('.sidebar-toggle-btn'); | |||||
let sidebar_wrapper = this.wrapper.find('.layout-side-section'); | |||||
if (this.disable_sidebar_toggle || !sidebar_wrapper.length) { | |||||
sidebar_toggle.remove(); | |||||
} else { | |||||
if ($(window).width() > 1024) { | |||||
sidebar_toggle.attr("title", __("Toggle Sidebar")).tooltip({ | |||||
delay: {"show": 600, "hide": 100}, | |||||
trigger: "hover", | |||||
}); | |||||
} | |||||
sidebar_toggle.click(() => { | |||||
if (xhiveframework.utils.is_xs() || xhiveframework.utils.is_sm()) { | |||||
this.setup_overlay_sidebar(); | |||||
} else { | |||||
sidebar_wrapper.toggle(); | |||||
} | |||||
$(document.body).trigger('toggleSidebar'); | |||||
this.update_sidebar_icon(); | |||||
}); | |||||
} | |||||
}, | |||||
setup_overlay_sidebar() { | |||||
let overlay_sidebar = this.sidebar.find('.overlay-sidebar').addClass('opened'); | |||||
$('<div class="close-sidebar">').hide().appendTo(this.sidebar).fadeIn(); | |||||
let scroll_container = $('html').css("overflow-y", "hidden"); | |||||
this.sidebar.find(".close-sidebar").on('click', (e) => close_sidebar(e)); | |||||
this.sidebar.on("click", "button:not(.dropdown-toggle)", (e) => close_sidebar(e)); | |||||
let close_sidebar = () => { | |||||
scroll_container.css("overflow-y", ""); | |||||
this.sidebar.find("div.close-sidebar").fadeOut(() => { | |||||
overlay_sidebar.removeClass('opened').find('.dropdown-toggle').removeClass('text-muted'); | |||||
}); | |||||
}; | |||||
}, | |||||
update_sidebar_icon() { | |||||
let sidebar_toggle = $('.page-head').find('.sidebar-toggle-btn'); | |||||
let sidebar_toggle_icon = sidebar_toggle.find('.sidebar-toggle-icon'); | |||||
let sidebar_wrapper = this.wrapper.find('.layout-side-section'); | |||||
let is_sidebar_visible = $(sidebar_wrapper).is(":visible"); | |||||
sidebar_toggle_icon.html(xhiveframework.utils.icon(is_sidebar_visible ? 'sidebar-collapse' : 'sidebar-expand', 'md')); | |||||
}, | |||||
set_indicator: function (label, color) { | |||||
this.clear_indicator().removeClass("hide").html(`<span>${label}</span>`).addClass(color); | |||||
}, | |||||
add_action_icon: function (icon, click, css_class = '', tooltip_label) { | |||||
const button = $(` | |||||
<button class="text-muted btn btn-default ${css_class} icon-btn"> | |||||
${xhiveframework.utils.icon(icon)} | |||||
</button> | |||||
`); | |||||
button.appendTo(this.icon_group.removeClass("hide")); | |||||
button.click(click); | |||||
button.attr("title", __(tooltip_label || xhiveframework.unscrub(icon))) | |||||
.tooltip({delay: {"show": 600, "hide": 100}, trigger: "hover"}); | |||||
return button; | |||||
}, | |||||
clear_indicator: function () { | |||||
return this.indicator.removeClass().addClass("indicator-pill whitespace-nowrap hide"); | |||||
}, | |||||
get_icon_label: function (icon, label) { | |||||
let icon_name = icon; | |||||
let size = 'xs'; | |||||
if (typeof icon === 'object') { | |||||
icon_name = icon.icon; | |||||
size = icon.size || 'xs'; | |||||
} | |||||
return `${icon ? xhiveframework.utils.icon(icon_name, size) : ''} <span class="hidden-xs"> ${__(label)} </span>`; | |||||
}, | |||||
set_action: function (btn, opts) { | |||||
let me = this; | |||||
if (opts.icon) { | |||||
opts.label = this.get_icon_label(opts.icon, opts.label); | |||||
} | |||||
this.clear_action_of(btn); | |||||
btn.removeClass("hide") | |||||
.prop("disabled", false) | |||||
.html(opts.label) | |||||
.on("click", function () { | |||||
let response = opts.click.apply(this); | |||||
me.btn_disable_enable(btn, response); | |||||
}); | |||||
if (opts.working_label) { | |||||
btn.attr("data-working-label", opts.working_label); | |||||
} | |||||
// alt shortcuts | |||||
let text_span = btn.find('span'); | |||||
xhiveframework.ui.keys | |||||
.get_shortcut_group(this) | |||||
.add(btn, text_span.length ? text_span : btn); | |||||
}, | |||||
set_primary_action: function (label, click, icon, working_label) { | |||||
this.set_action(this.btn_primary, { | |||||
label: label, | |||||
click: click, | |||||
icon: icon, | |||||
working_label: working_label | |||||
}); | |||||
return this.btn_primary; | |||||
}, | |||||
set_secondary_action: function (label, click, icon, working_label) { | |||||
this.set_action(this.btn_secondary, { | |||||
label: label, | |||||
click: click, | |||||
icon: icon, | |||||
working_label: working_label | |||||
}); | |||||
return this.btn_secondary; | |||||
}, | |||||
clear_action_of: function (btn) { | |||||
btn.addClass("hide").unbind("click").removeAttr("data-working-label"); | |||||
}, | |||||
clear_primary_action: function () { | |||||
this.clear_action_of(this.btn_primary); | |||||
}, | |||||
clear_secondary_action: function () { | |||||
this.clear_action_of(this.btn_secondary); | |||||
}, | |||||
clear_actions: function () { | |||||
this.clear_primary_action(); | |||||
this.clear_secondary_action(); | |||||
}, | |||||
clear_custom_actions() { | |||||
this.custom_actions.addClass("hide").empty(); | |||||
}, | |||||
clear_icons: function () { | |||||
this.icon_group.addClass("hide").empty(); | |||||
}, | |||||
//--- Menu --// | |||||
add_menu_item: function (label, click, standard, shortcut) { | |||||
return this.add_dropdown_item({ | |||||
label, | |||||
click, | |||||
standard, | |||||
parent: this.menu, | |||||
shortcut | |||||
}); | |||||
}, | |||||
add_custom_menu_item: function (parent, label, click, standard, shortcut, icon = null) { | |||||
return this.add_dropdown_item({ | |||||
label, | |||||
click, | |||||
standard, | |||||
parent: parent, | |||||
shortcut, | |||||
icon | |||||
}); | |||||
}, | |||||
clear_menu: function () { | |||||
this.clear_btn_group(this.menu); | |||||
}, | |||||
show_menu: function () { | |||||
this.menu_btn_group.removeClass("hide"); | |||||
}, | |||||
hide_menu: function () { | |||||
this.menu_btn_group.addClass("hide"); | |||||
}, | |||||
show_icon_group: function () { | |||||
this.icon_group.removeClass("hide"); | |||||
}, | |||||
hide_icon_group: function () { | |||||
this.icon_group.addClass("hide"); | |||||
}, | |||||
//--- Actions Menu--// | |||||
show_actions_menu: function () { | |||||
this.actions_btn_group.removeClass("hide"); | |||||
}, | |||||
hide_actions_menu: function () { | |||||
this.actions_btn_group.addClass("hide"); | |||||
}, | |||||
add_action_item: function (label, click, standard) { | |||||
return this.add_dropdown_item({ | |||||
label, | |||||
click, | |||||
standard, | |||||
parent: this.actions | |||||
}); | |||||
}, | |||||
add_actions_menu_item: function (label, click, standard) { | |||||
return this.add_dropdown_item({ | |||||
label, | |||||
click, | |||||
standard, | |||||
parent: this.actions, | |||||
show_parent: false | |||||
}); | |||||
}, | |||||
clear_actions_menu: function () { | |||||
this.clear_btn_group(this.actions); | |||||
}, | |||||
//-- Generic --// | |||||
/* | |||||
* Add label to given drop down menu. If label, is already contained in the drop | |||||
* down menu, it will be ignored. | |||||
* @param {string} label - Text for the drop down menu | |||||
* @param {function} click - function to be called when `label` is clicked | |||||
* @param {Boolean} standard | |||||
* @param {object} parent - DOM object representing the parent of the drop down item lists | |||||
* @param {string} shortcut - Keyboard shortcut associated with the element | |||||
* @param {Boolean} show_parent - Whether to show the dropdown button if dropdown item is added | |||||
*/ | |||||
add_dropdown_item: function ({label, click, standard, parent, shortcut, show_parent = true, icon = null}) { | |||||
if (show_parent) { | |||||
parent.parent().removeClass("hide"); | |||||
} | |||||
let $link = this.is_in_group_button_dropdown(parent, 'li > a.grey-link', label); | |||||
if ($link) return $link; | |||||
let $li; | |||||
let $icon = ``; | |||||
if (icon) { | |||||
$icon = `<span class="menu-item-icon">${xhiveframework.utils.icon(icon)}</span>`; | |||||
} | |||||
if (shortcut) { | |||||
let shortcut_obj = this.prepare_shortcut_obj(shortcut, click, label); | |||||
$li = $(` | |||||
<li> | |||||
<a class="grey-link dropdown-item" href="#" onClick="return false;"> | |||||
${$icon} | |||||
<span class="menu-item-label">${label}</span> | |||||
<kbd class="pull-right"> | |||||
<span>${shortcut_obj.shortcut_label}</span> | |||||
</kbd> | |||||
</a> | |||||
</li> | |||||
`); | |||||
xhiveframework.ui.keys.add_shortcut(shortcut_obj); | |||||
} else { | |||||
$li = $(` | |||||
<li> | |||||
<a class="grey-link dropdown-item" href="#" onClick="return false;"> | |||||
${$icon} | |||||
<span class="menu-item-label">${label}</span> | |||||
</a> | |||||
</li> | |||||
`); | |||||
} | |||||
$link = $li.find("a").on("click", click); | |||||
if (standard) { | |||||
$li.appendTo(parent); | |||||
} else { | |||||
this.divider = parent.find(".dropdown-divider"); | |||||
if (!this.divider.length) { | |||||
this.divider = $('<li class="dropdown-divider user-action"></li>').prependTo(parent); | |||||
} | |||||
$li.addClass("user-action").insertBefore(this.divider); | |||||
} | |||||
// alt shortcut | |||||
xhiveframework.ui.keys | |||||
.get_shortcut_group(parent.get(0)) | |||||
.add($link, $link.find('.menu-item-label')); | |||||
return $link; | |||||
}, | |||||
prepare_shortcut_obj(shortcut, click, label) { | |||||
let shortcut_obj; | |||||
// convert to object, if shortcut string passed | |||||
if (typeof shortcut === 'string') { | |||||
shortcut_obj = {shortcut}; | |||||
} else { | |||||
shortcut_obj = shortcut; | |||||
} | |||||
// label | |||||
if (xhiveframework.utils.is_mac()) { | |||||
shortcut_obj.shortcut_label = shortcut_obj.shortcut.replace('Ctrl', '⌘'); | |||||
} else { | |||||
shortcut_obj.shortcut_label = shortcut_obj.shortcut; | |||||
} | |||||
// actual shortcut string | |||||
shortcut_obj.shortcut = shortcut_obj.shortcut.toLowerCase(); | |||||
// action is button click | |||||
if (!shortcut_obj.action) { | |||||
shortcut_obj.action = click; | |||||
} | |||||
// shortcut description can be button label | |||||
if (!shortcut_obj.description) { | |||||
shortcut_obj.description = label; | |||||
} | |||||
// page | |||||
shortcut_obj.page = this; | |||||
return shortcut_obj; | |||||
}, | |||||
/* | |||||
* Check if there already exists a button with a specified label in a specified button group | |||||
* @param {object} parent - This should be the `ul` of the button group. | |||||
* @param {string} selector - CSS Selector of the button to be searched for. By default, it is `li`. | |||||
* @param {string} label - Label of the button | |||||
*/ | |||||
is_in_group_button_dropdown: function (parent, selector, label) { | |||||
if (!selector) selector = 'li'; | |||||
if (!label || !parent) return false; | |||||
const result = $(parent).find(`${selector}:contains('${label}')`) | |||||
.filter(function () { | |||||
let item = $(this).html(); | |||||
return $(item).attr('data-label') === label; | |||||
}); | |||||
return result.length > 0 && result; | |||||
}, | |||||
clear_btn_group: function (parent) { | |||||
parent.empty(); | |||||
parent.parent().addClass("hide"); | |||||
}, | |||||
add_divider: function () { | |||||
return $('<li class="dropdown-divider"></li>').appendTo(this.menu); | |||||
}, | |||||
get_or_add_inner_group_button: function (label) { | |||||
var $group = this.inner_toolbar.find(`.inner-group-button[data-label="${encodeURIComponent(label)}"]`); | |||||
if (!$group.length) { | |||||
$group = $( | |||||
`<div class="inner-group-button" data-label="${encodeURIComponent(label)}"> | |||||
<button type="button" class="btn btn-default ellipsis" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> | |||||
${label} | |||||
${xhiveframework.utils.icon('select', 'xs')} | |||||
</button> | |||||
<div role="menu" class="dropdown-menu"></div> | |||||
</div>` | |||||
).appendTo(this.inner_toolbar); | |||||
} | |||||
return $group; | |||||
}, | |||||
get_inner_group_button: function (label) { | |||||
return this.inner_toolbar.find(`.inner-group-button[data-label="${encodeURIComponent(label)}"]`); | |||||
}, | |||||
set_inner_btn_group_as_primary: function (label) { | |||||
this.get_or_add_inner_group_button(label).find("button").removeClass("btn-default").addClass("btn-primary"); | |||||
}, | |||||
btn_disable_enable: function (btn, response) { | |||||
if (response && response.then) { | |||||
btn.prop('disabled', true); | |||||
response.then(() => { | |||||
btn.prop('disabled', false); | |||||
}) | |||||
} else if (response && response.always) { | |||||
btn.prop('disabled', true); | |||||
response.always(() => { | |||||
btn.prop('disabled', false); | |||||
}); | |||||
} | |||||
}, | |||||
/* | |||||
* Add button to button group. If there exists another button with the same label, | |||||
* `add_inner_button` will not add the new button to the button group even if the callback | |||||
* function is different. | |||||
* | |||||
* @param {string} label - Label of the button to be added to the group | |||||
* @param {object} action - function to be called when button is clicked | |||||
* @param {string} group - Label of the group button | |||||
*/ | |||||
add_inner_button: function (label, action, group, type = "default") { | |||||
var me = this; | |||||
let _action = function () { | |||||
let btn = $(this); | |||||
let response = action(); | |||||
me.btn_disable_enable(btn, response); | |||||
}; | |||||
if (group) { | |||||
var $group = this.get_or_add_inner_group_button(group); | |||||
$(this.inner_toolbar).removeClass("hide"); | |||||
if (!this.is_in_group_button_dropdown($group.find(".dropdown-menu"), 'a', label)) { | |||||
return $(`<a class="dropdown-item" href="#" onclick="return false;" data-label="${encodeURIComponent(label)}">${label}</a>`) | |||||
.on('click', _action) | |||||
.appendTo($group.find(".dropdown-menu")); | |||||
} | |||||
} else { | |||||
let button = this.inner_toolbar.find(`button[data-label="${encodeURIComponent(label)}"]`); | |||||
if (button.length == 0) { | |||||
button = $(`<button data-label="${encodeURIComponent(label)}" class="btn btn-${type} ellipsis"> | |||||
${__(label)} | |||||
</button>`); | |||||
button.on("click", _action); | |||||
button.appendTo(this.inner_toolbar.removeClass("hide")); | |||||
} | |||||
return button; | |||||
} | |||||
}, | |||||
remove_inner_button: function (label, group) { | |||||
if (typeof label === 'string') { | |||||
label = [label]; | |||||
} | |||||
// translate | |||||
label = label.map(l => __(l)); | |||||
if (group) { | |||||
var $group = this.get_inner_group_button(__(group)); | |||||
if ($group.length) { | |||||
$group.find(`.dropdown-item[data-label="${encodeURIComponent(label)}"]`).remove(); | |||||
} | |||||
if ($group.find('.dropdown-item').length === 0) $group.remove(); | |||||
} else { | |||||
this.inner_toolbar.find(`button[data-label="${encodeURIComponent(label)}"]`).remove(); | |||||
} | |||||
}, | |||||
change_inner_button_type: function (label, group, type) { | |||||
let btn; | |||||
if (group) { | |||||
var $group = this.get_inner_group_button(__(group)); | |||||
if ($group.length) { | |||||
btn = $group.find(`.dropdown-item[data-label="${encodeURIComponent(label)}"]`); | |||||
} | |||||
} else { | |||||
btn = this.inner_toolbar.find(`button[data-label="${encodeURIComponent(label)}"]`); | |||||
} | |||||
if (btn) { | |||||
btn.removeClass().addClass(`btn btn-${type} ellipsis`); | |||||
} | |||||
}, | |||||
add_inner_message: function (message) { | |||||
let $message = $(`<span class='inner-page-message text-muted small'>${message}</div>`); | |||||
this.inner_toolbar.find('.inner-page-message').remove(); | |||||
this.inner_toolbar.removeClass("hide").prepend($message); | |||||
return $message; | |||||
}, | |||||
clear_inner_toolbar: function () { | |||||
this.inner_toolbar.empty().addClass("hide"); | |||||
}, | |||||
//-- Sidebar --// | |||||
add_sidebar_item: function (label, action, insert_after, prepend) { | |||||
var parent = this.sidebar.find(".sidebar-menu.standard-actions"); | |||||
var li = $('<li>'); | |||||
var link = $('<a>').html(label).on("click", action).appendTo(li); | |||||
if (insert_after) { | |||||
li.insertAfter(parent.find(insert_after)); | |||||
} else { | |||||
if (prepend) { | |||||
li.prependTo(parent); | |||||
} else { | |||||
li.appendTo(parent); | |||||
} | |||||
} | |||||
return link; | |||||
}, | |||||
//---// | |||||
clear_user_actions: function () { | |||||
this.menu.find(".user-action").remove(); | |||||
}, | |||||
// page::title | |||||
get_title_area: function () { | |||||
return this.$title_area; | |||||
}, | |||||
set_title: function (title, icon = null, strip = true, tab_title = "") { | |||||
if (!title) title = ""; | |||||
if (strip) { | |||||
title = strip_html(title); | |||||
} | |||||
this.title = title; | |||||
xhiveframework.utils.set_title(tab_title || title); | |||||
if (icon) { | |||||
title = `${xhiveframework.utils.icon(icon)} ${title}`; | |||||
} | |||||
let title_wrapper = this.$title_area.find(".title-text"); | |||||
title_wrapper.html(title); | |||||
title_wrapper.attr('title', this.title); | |||||
}, | |||||
set_title_sub: function (txt) { | |||||
// strip icon | |||||
this.$sub_title_area.html(txt).toggleClass("hide", !!!txt); | |||||
}, | |||||
get_main_icon: function (icon) { | |||||
return this.$title_area.find(".title-icon") | |||||
.html('<i class="' + icon + ' fa-fw"></i> ') | |||||
.toggle(true); | |||||
}, | |||||
add_help_button: function (txt) { | |||||
// | |||||
}, | |||||
add_button: function (label, click, opts) { | |||||
if (!opts) opts = {}; | |||||
let button = $(`<button | |||||
class="btn ${opts.btn_class || 'btn-default'} ${opts.btn_size || 'btn-sm'} ellipsis"> | |||||
${opts.icon ? xhiveframework.utils.icon(opts.icon) : ''} | |||||
${label} | |||||
</button>`); | |||||
button.appendTo(this.custom_actions); | |||||
button.on('click', click); | |||||
this.custom_actions.removeClass('hide'); | |||||
return button; | |||||
}, | |||||
add_custom_button_group: function (label, icon, parent) { | |||||
let dropdown_label = `<span class="hidden-xs"> | |||||
<span class="custom-btn-group-label">${__(label)}</span> | |||||
${xhiveframework.utils.icon('select', 'xs')} | |||||
</span>`; | |||||
if (icon) { | |||||
dropdown_label = `<span class="hidden-xs"> | |||||
${xhiveframework.utils.icon(icon)} | |||||
<span class="custom-btn-group-label">${__(label)}</span> | |||||
${xhiveframework.utils.icon('select', 'xs')} | |||||
</span> | |||||
<span class="visible-xs"> | |||||
${xhiveframework.utils.icon(icon)} | |||||
</span>`; | |||||
} | |||||
let custom_btn_group = $(` | |||||
<div class="custom-btn-group"> | |||||
<button type="button" class="btn btn-default btn-sm ellipsis" data-toggle="dropdown" aria-expanded="false"> | |||||
${dropdown_label} | |||||
</button> | |||||
<ul class="dropdown-menu" role="menu"></ul> | |||||
</div> | |||||
`); | |||||
if (!parent) parent = this.custom_actions; | |||||
parent.removeClass('hide').append(custom_btn_group); | |||||
return custom_btn_group.find('.dropdown-menu'); | |||||
}, | |||||
add_dropdown_button: function (parent, label, click, icon) { | |||||
xhiveframework.ui.toolbar.add_dropdown_button(parent, label, click, icon); | |||||
}, | |||||
// page::form | |||||
add_label: function (label) { | |||||
this.show_form(); | |||||
return $("<label class='col-md-1 page-only-label'>" + label + " </label>") | |||||
.appendTo(this.page_form); | |||||
}, | |||||
add_select: function (label, options) { | |||||
var field = this.add_field({label: label, fieldtype: "Select"}); | |||||
return field.$wrapper.find("select").empty().add_options(options); | |||||
}, | |||||
add_data: function (label) { | |||||
var field = this.add_field({label: label, fieldtype: "Data"}); | |||||
return field.$wrapper.find("input").attr("placeholder", label); | |||||
}, | |||||
add_date: function (label, date) { | |||||
var field = this.add_field({label: label, fieldtype: "Date", "default": date}); | |||||
return field.$wrapper.find("input").attr("placeholder", label); | |||||
}, | |||||
add_check: function (label) { | |||||
return $("<div class='checkbox'><label><input type='checkbox'>" + label + "</label></div>") | |||||
.appendTo(this.page_form) | |||||
.find("input"); | |||||
}, | |||||
add_break: function () { | |||||
// add further fields in the next line | |||||
this.page_form.append('<div class="clearfix invisible-xs"></div>'); | |||||
}, | |||||
add_field: function (df, parent) { | |||||
this.show_form(); | |||||
if (!df.placeholder) { | |||||
df.placeholder = df.label; | |||||
} | |||||
df.input_class = 'input-xs'; | |||||
var f = xhiveframework.ui.form.make_control({ | |||||
df: df, | |||||
parent: parent || this.page_form, | |||||
only_input: df.fieldtype == "Check" ? false : true, | |||||
}) | |||||
f.refresh(); | |||||
$(f.wrapper) | |||||
.addClass('col-md-2') | |||||
.attr("title", __(df.label)).tooltip({ | |||||
delay: {"show": 600, "hide": 100}, | |||||
trigger: "hover" | |||||
}); | |||||
// html fields in toolbar are only for display | |||||
if (df.fieldtype == 'HTML') { | |||||
return; | |||||
} | |||||
// hidden fields dont have $input | |||||
if (!f.$input) f.make_input(); | |||||
f.$input.attr("placeholder", __(df.label)); | |||||
if (df.fieldtype === "Check") { | |||||
$(f.wrapper).find(":first-child") | |||||
.removeClass("col-md-offset-4 col-md-8"); | |||||
} | |||||
if (df.fieldtype == "Button") { | |||||
$(f.wrapper).find(".page-control-label").html(" "); | |||||
f.$input.addClass("btn-xs").css({"width": "100%", "margin-top": "-1px"}); | |||||
} | |||||
if (df["default"]) | |||||
f.set_input(df["default"]) | |||||
this.fields_dict[df.fieldname || df.label] = f; | |||||
return f; | |||||
}, | |||||
clear_fields: function () { | |||||
this.page_form.empty(); | |||||
}, | |||||
show_form: function () { | |||||
this.page_form.removeClass("hide"); | |||||
}, | |||||
hide_form: function () { | |||||
this.page_form.addClass("hide"); | |||||
}, | |||||
get_form_values: function () { | |||||
var values = {}; | |||||
this.page_form.fields_dict.forEach(function (field, key) { | |||||
values[key] = field.get_value(); | |||||
}); | |||||
return values; | |||||
}, | |||||
add_view: function (name, html) { | |||||
let element = html; | |||||
if (typeof (html) === "string") { | |||||
element = $(html); | |||||
} | |||||
this.views[name] = element.appendTo($(this.wrapper).find(".page-content")); | |||||
if (!this.current_view) { | |||||
this.current_view = this.views[name]; | |||||
} else { | |||||
this.views[name].toggle(false); | |||||
} | |||||
return this.views[name]; | |||||
}, | |||||
set_view: function (name) { | |||||
if (this.current_view_name === name) | |||||
return; | |||||
this.current_view && this.current_view.toggle(false); | |||||
this.current_view = this.views[name]; | |||||
this.previous_view_name = this.current_view_name; | |||||
this.current_view_name = name; | |||||
this.views[name].toggle(true); | |||||
this.wrapper.trigger('view-change'); | |||||
}, | |||||
}); |
@@ -0,0 +1,145 @@ | |||||
<div class="dv-navbar-overlay"></div> | |||||
<div class="dv-navbar datavalue-nav"> | |||||
<div class="container-fluid"> | |||||
<div class="dv-nav-left"> | |||||
<button type="button" class="btn-open-mobile-menu"><i class="far fa-bars"></i></button> | |||||
<button type="button" class="btn-open-modules"><i class="flaticon-menu"></i></button> | |||||
<div class="logo" id="datavalue-app-logo" :class="logo_class"><a href="/app"><img v-if="logo_path && logo_path.length" :src="logo_path"></a></div> | |||||
<div class="navbar-breadcrumbs"> | |||||
<ul class="nav navbar-nav d-none d-sm-flex" id="navbar-breadcrumbs"></ul> | |||||
</div> | |||||
</div> | |||||
<div class="dv-nav-right"> | |||||
<ul class="list-unstyled"> | |||||
<li class="nav-item dropdown dropdown-user" id="header-navbar-user"> | |||||
<a class="nav-link dropdown-toggle dropdown-user-link" data-toggle="dropdown"> | |||||
<span class="dv-nav-avatar"> | |||||
{{ avatar }} | |||||
<span class="avatar-status-online"></span> | |||||
</span> | |||||
<div class="dv-user-info"> | |||||
<span class="user-name">[[user.full_name]]</span> | |||||
<span class="user-status">[[user_type]]</span> | |||||
</div> | |||||
</a> | |||||
<div class="dropdown-menu dropdown-menu-right" aria-labelledby="dropdown-user"> | |||||
<div class="dropdown-item dropdown-item-username show-on-mobile"> | |||||
[[user.full_name]] | |||||
</div> | |||||
<div class="dropdown-divider show-on-mobile"></div> | |||||
{% for item in navbar_settings.settings_dropdown %} | |||||
{% if (!item.hidden) { %} | |||||
{% if (item.route) { %} | |||||
<a class="dropdown-item" href="{{ item.route }}"> | |||||
{%= __(item.item_label) %} | |||||
</a> | |||||
{% } else if (item.action && item.action!="new xhiveframework.ui.ThemeSwitcher().show()") { %} | |||||
<a class="dropdown-item" onclick="return {{ item.action }}"> | |||||
{%= __(item.item_label) %} | |||||
</a> | |||||
{% } else { %} | |||||
<div class="dropdown-divider"></div> | |||||
{% } %} | |||||
{% } %} | |||||
{% endfor %} | |||||
</div> | |||||
</li> | |||||
<li class="nav-item dropdown dv-dropdown-notifications"> | |||||
<a class="nav-link notifications-icon animated-tada" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true" href="#" onclick="return false;"> | |||||
<span class="notifications-seen"> | |||||
<i class="far fa-bell animated-icon"></i> | |||||
</span> | |||||
<span class="notifications-unseen"> | |||||
<svg class="icon icon-md"><use href="#icon-notification-with-indicator"></use></svg> | |||||
</span> | |||||
</a> | |||||
<div class="dropdown-menu notifications-list dropdown-menu-right" role="menu"> | |||||
<div class="notification-list-header"> | |||||
<div class="header-items"></div> | |||||
<div class="header-actions"></div> | |||||
</div> | |||||
<div class="notification-list-body"> | |||||
<div class="panel-notifications"></div> | |||||
<div class="panel-events"></div> | |||||
</div> | |||||
</div> | |||||
</li> | |||||
<li class="nav-item dropdown dropdown-files"> | |||||
<button type="button" class="nav-link files-icon animated-tada"> | |||||
<i class="far fa-folder-open animated-icon"></i> | |||||
</button> | |||||
</li> | |||||
<li class="nav-item dropdown-full-screen"> | |||||
<button type="button" class="nav-link full-screen-icon animated-tada"> | |||||
<i class="far fa-expand animated-icon"></i> | |||||
</button> | |||||
</li> | |||||
<li class="nav-item dropdown-full-screen"> | |||||
<button type="button" class="nav-link open-theme-setting animated-tada"> | |||||
<i class="far fa-palette animated-icon"></i> | |||||
</button> | |||||
</li> | |||||
<li class="nav-item dropdown-search"> | |||||
<button type="button" class="nav-link open-search animated-tada"> | |||||
<i class="far fa-search"></i> | |||||
</button> | |||||
</li> | |||||
<li class="nav-item dropdown dropdown-language" id="header-navbar-change-lang"> | |||||
<a class="nav-link dropdown-lang-link" data-toggle="dropdown"> | |||||
<span :class="lang_list[active_lang].flag" v-if="hide_language_icon!=1"></span> | |||||
[[lang_list[active_lang].label]] | |||||
<span> | |||||
<svg class="icon icon-xs"><use href="#icon-small-down"></use></svg> | |||||
</span> | |||||
</a> | |||||
<div class="dropdown-menu dropdown-menu-right"> | |||||
<a class="dropdown-item" data-lang="EN"> | |||||
<span class="dv-lang-flag lang-en" v-if="hide_language_icon!=1"></span> EN | |||||
</a> | |||||
<a class="dropdown-item" data-lang="AR"> | |||||
<span class="dv-lang-flag lang-ar" v-if="hide_language_icon!=1"></span> AR | |||||
</a> | |||||
</div> | |||||
</li> | |||||
{% if(show_help_icon) { %} | |||||
<li class="nav-item dropdown dropdown-language"> | |||||
<a class="nav-link dropdown-lang-link animated-tada" data-toggle="dropdown" href="#" onclick="return false;"> | |||||
{{ __("Help") }} | |||||
<span> | |||||
<svg class="icon icon-xs"><use href="#icon-small-down"></use></svg> | |||||
</span> | |||||
</a> | |||||
<div class="dropdown-menu dropdown-menu-right" id="toolbar-help" role="menu" style="width:auto;"> | |||||
<div id="help-links"></div> | |||||
<div class="dropdown-divider documentation-links"></div> | |||||
{% for item in navbar_settings.help_dropdown %} | |||||
{% if (!item.hidden) { %} | |||||
{% if (item.route) { %} | |||||
<a class="dropdown-item" href="{{ item.route }}"> | |||||
{%= __(item.item_label) %} | |||||
</a> | |||||
{% } else if (item.action) { %} | |||||
<a class="dropdown-item" onclick="return {{ item.action }}"> | |||||
{%= __(item.item_label) %} | |||||
</a> | |||||
{% } else { %} | |||||
<div class="dropdown-divider"></div> | |||||
{% } %} | |||||
{% } %} | |||||
{% endfor %} | |||||
</div> | |||||
</li> | |||||
{% } %} | |||||
</ul> | |||||
</div> | |||||
<form class="dv-nav-search" onsubmit="return false;"> | |||||
<input id="navbar-search" type="text" class="form-control" placeholder="{%= __(" Search or type a command (Ctrl + G)") %}" aria-haspopup="true"> | |||||
<span class="search-icon"><i class="fal fa-search"></i></span> | |||||
<button type="button" class="dv-nav-search-close"><i class="far fa-times"></i></button> | |||||
</form> | |||||
</div> | |||||
</div> | |||||
<header class="navbar navbar-expand sticky-top" role="navigation" style="display:none;"> | |||||
<div class="container"> | |||||
</div> | |||||
</header> |
@@ -0,0 +1,52 @@ | |||||
// open-theme-setting | |||||
$(document).on('click', '.theme-setting-colors-select.theme-setting-modal button', function (event) { | |||||
event.preventDefault(); | |||||
$('.theme-setting-colors-select.theme-setting-modal button').removeClass('active'); | |||||
$(this).addClass('active'); | |||||
}); | |||||
$(document).on('click', '.open-theme-setting', function (event) { | |||||
event.preventDefault(); | |||||
let colors_list = ['Blue', 'Green', 'Red', 'Orange', 'Yellow', 'Pink', 'Violet'] | |||||
let d = new xhiveframework.ui.Dialog({ | |||||
title: __('Theme Settings'), | |||||
fields: [ | |||||
{ | |||||
label: 'Dark Style', | |||||
fieldname: 'dark_style', | |||||
fieldtype: 'Check', | |||||
default: ($('html').attr('data-theme') == 'dark' && $('body').hasClass('dv-dark-style')) ? 1 : 0 | |||||
}, | |||||
{ | |||||
label: 'Colors', | |||||
fieldname: 'colors_icons', | |||||
fieldtype: 'HTML', | |||||
options: ` | |||||
<div class="theme-setting-colors-select theme-setting-modal"> | |||||
<h4>${__('Theme Colors')}</h4> | |||||
<div class="dv-row dv-row-sm"> | |||||
${colors_list.map(color => `<div class="dv-col"><button type="button" class="${($('body').data('theme-color') == color) ? 'active' : ''}" data-color="${color}" data-class="dv-${color}-style">${color}</button></div>`).join("")} | |||||
</div> | |||||
</div> | |||||
` | |||||
} | |||||
], | |||||
primary_action_label: __('Save Settings'), | |||||
primary_action(values) { | |||||
let active_btn = $('.theme-setting-colors-select.theme-setting-modal button.active'); | |||||
let data = { | |||||
color_name: active_btn.data('color'), | |||||
color_class: active_btn.data('class'), | |||||
dark_style: values.dark_style | |||||
} | |||||
xhiveframework.db.set_value('Theme Settings', 'Theme Settings', { | |||||
'dark_view': data.dark_style, | |||||
'theme_color': data.color_name | |||||
}, function () { | |||||
xhiveframework.ui.toolbar.clear_cache(); | |||||
setTimeout(() => d.hide(), 1000); | |||||
}); | |||||
} | |||||
}); | |||||
d.show(); | |||||
}); |
@@ -0,0 +1,293 @@ | |||||
// Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||||
// MIT License. See license.txt | |||||
xhiveframework.provide("xhiveframework.ui.toolbar"); | |||||
xhiveframework.provide("xhiveframework.search"); | |||||
xhiveframework.ui.toolbar.Toolbar = class { | |||||
constructor() { | |||||
$("header").replaceWith( | |||||
xhiveframework.render_template("navbar", { | |||||
avatar: xhiveframework.avatar(xhiveframework.session.user, "avatar-medium"), | |||||
navbar_settings: xhiveframework.boot.navbar_settings, | |||||
show_help_icon: ($('body').data('show-help-icon') == 1) ? true : false, | |||||
}) | |||||
); | |||||
$(".dropdown-toggle").dropdown(); | |||||
this.setup_awesomebar(); | |||||
this.setup_notifications(); | |||||
this.setup_help(); | |||||
this.make(); | |||||
} | |||||
make() { | |||||
this.bind_events(); | |||||
$(document).trigger("toolbar_setup"); | |||||
} | |||||
bind_events() { | |||||
// clear all custom menus on page change | |||||
$(document).on("page-change", function () { | |||||
$("header .navbar .custom-menu").remove(); | |||||
}); | |||||
//focus search-modal on show in mobile view | |||||
$("#search-modal").on("shown.bs.modal", function () { | |||||
var search_modal = $(this); | |||||
setTimeout(function () { | |||||
search_modal.find("#modal-search").focus(); | |||||
}, 300); | |||||
}); | |||||
$(".navbar-toggle-full-width").click(() => { | |||||
xhiveframework.ui.toolbar.toggle_full_width(); | |||||
}); | |||||
} | |||||
setup_help() { | |||||
if (!xhiveframework.boot.desk_settings.notifications) { | |||||
// hide the help section | |||||
$(".navbar .vertical-bar").removeClass("d-sm-block"); | |||||
$(".dropdown-help").removeClass("d-lg-block"); | |||||
return; | |||||
} | |||||
xhiveframework.provide("xhiveframework.help"); | |||||
xhiveframework.help.show_results = show_results; | |||||
this.search = new xhiveframework.search.SearchDialog(); | |||||
xhiveframework.provide("xhiveframework.searchdialog"); | |||||
xhiveframework.searchdialog.search = this.search; | |||||
$(".dropdown-help .dropdown-toggle").on("click", function () { | |||||
$(".dropdown-help input").focus(); | |||||
}); | |||||
$(".dropdown-help .dropdown-menu").on("click", "input, button", function (e) { | |||||
e.stopPropagation(); | |||||
}); | |||||
$("#input-help").on("keydown", function (e) { | |||||
if (e.which == 13) { | |||||
$(this).val(""); | |||||
} | |||||
}); | |||||
$(document).on("page-change", function () { | |||||
var $help_links = $(".dropdown-help #help-links"); | |||||
$help_links.html(""); | |||||
var route = xhiveframework.get_route_str(); | |||||
var breadcrumbs = route.split("/"); | |||||
var links = []; | |||||
for (var i = 0; i < breadcrumbs.length; i++) { | |||||
var r = route.split("/", i + 1); | |||||
var key = r.join("/"); | |||||
var help_links = xhiveframework.help.help_links[key] || []; | |||||
links = $.merge(links, help_links); | |||||
} | |||||
if (links.length === 0) { | |||||
$help_links.next().hide(); | |||||
} else { | |||||
$help_links.next().show(); | |||||
} | |||||
for (var i = 0; i < links.length; i++) { | |||||
var link = links[i]; | |||||
var url = link.url; | |||||
$("<a>", { | |||||
href: url, | |||||
class: "dropdown-item", | |||||
text: __(link.label), | |||||
target: "_blank", | |||||
}).appendTo($help_links); | |||||
} | |||||
$(".dropdown-help .dropdown-menu").on("click", "a", show_results); | |||||
}); | |||||
var $result_modal = xhiveframework.get_modal("", ""); | |||||
$result_modal.addClass("help-modal"); | |||||
$(document).on("click", ".help-modal a", show_results); | |||||
function show_results(e) { | |||||
//edit links | |||||
var href = e.target.href; | |||||
if (href.indexOf("blob") > 0) { | |||||
window.open(href, "_blank"); | |||||
} | |||||
var path = $(e.target).attr("data-path"); | |||||
if (path) { | |||||
e.preventDefault(); | |||||
} | |||||
} | |||||
} | |||||
setup_awesomebar() { | |||||
if (xhiveframework.boot.desk_settings.search_bar) { | |||||
let awesome_bar = new xhiveframework.search.AwesomeBar(); | |||||
awesome_bar.setup("#navbar-search"); | |||||
// TODO: Remove this in v14 | |||||
xhiveframework.search.utils.make_function_searchable(function () { | |||||
xhiveframework.set_route("List", "Client Script"); | |||||
}, __("Custom Script List")); | |||||
} | |||||
} | |||||
setup_notifications() { | |||||
if (xhiveframework.boot.desk_settings.notifications && xhiveframework.session.user !== "Guest") { | |||||
this.notifications = new xhiveframework.ui.Notifications(); | |||||
} | |||||
} | |||||
}; | |||||
$.extend(xhiveframework.ui.toolbar, { | |||||
add_dropdown_button: function (parent, label, click, icon) { | |||||
var menu = xhiveframework.ui.toolbar.get_menu(parent); | |||||
if (menu.find("li:not(.custom-menu)").length && !menu.find(".divider").length) { | |||||
xhiveframework.ui.toolbar.add_menu_divider(menu); | |||||
} | |||||
return $( | |||||
'<li class="custom-menu"><a><i class="fa-fw ' + icon + '"></i> ' + label + "</a></li>" | |||||
) | |||||
.insertBefore(menu.find(".divider")) | |||||
.find("a") | |||||
.click(function () { | |||||
click.apply(this); | |||||
}); | |||||
}, | |||||
get_menu: function (label) { | |||||
return $("#navbar-" + label.toLowerCase()); | |||||
}, | |||||
add_menu_divider: function (menu) { | |||||
menu = typeof menu == "string" ? xhiveframework.ui.toolbar.get_menu(menu) : menu; | |||||
$('<li class="divider custom-menu"></li>').prependTo(menu); | |||||
}, | |||||
add_icon_link(route, icon, index, class_name) { | |||||
let parent_element = $(".navbar-right").get(0); | |||||
let new_element = $(`<li class="${class_name}"> | |||||
<a class="btn" href="${route}" title="${xhiveframework.utils.to_title_case( | |||||
class_name, | |||||
true | |||||
)}" aria-haspopup="true" aria-expanded="true"> | |||||
<div> | |||||
<i class="octicon ${icon}"></i> | |||||
</div> | |||||
</a> | |||||
</li>`).get(0); | |||||
parent_element.insertBefore(new_element, parent_element.children[index]); | |||||
}, | |||||
toggle_full_width() { | |||||
let fullwidth = JSON.parse(localStorage.container_fullwidth || "false"); | |||||
fullwidth = !fullwidth; | |||||
localStorage.container_fullwidth = fullwidth; | |||||
xhiveframework.ui.toolbar.set_fullwidth_if_enabled(); | |||||
$(document.body).trigger("toggleFullWidth"); | |||||
}, | |||||
set_fullwidth_if_enabled() { | |||||
let fullwidth = JSON.parse(localStorage.container_fullwidth || "false"); | |||||
$(document.body).toggleClass("full-width", fullwidth); | |||||
}, | |||||
show_shortcuts(e) { | |||||
e.preventDefault(); | |||||
xhiveframework.ui.keys.show_keyboard_shortcut_dialog(); | |||||
return false; | |||||
}, | |||||
}); | |||||
xhiveframework.ui.toolbar.clear_cache = xhiveframework.utils.throttle(function () { | |||||
xhiveframework.assets.clear_local_storage(); | |||||
xhiveframework.xcall("xhiveframework.sessions.clear").then((message) => { | |||||
xhiveframework.show_alert({ | |||||
message: message, | |||||
indicator: "info", | |||||
}); | |||||
location.reload(true); | |||||
}); | |||||
}, 10000); | |||||
xhiveframework.ui.toolbar.show_about = function () { | |||||
try { | |||||
xhiveframework.ui.misc.about(); | |||||
} catch (e) { | |||||
console.log(e); | |||||
} | |||||
return false; | |||||
}; | |||||
xhiveframework.ui.toolbar.route_to_user = function () { | |||||
xhiveframework.set_route("Form", "User", xhiveframework.session.user); | |||||
}; | |||||
xhiveframework.ui.toolbar.view_website = function () { | |||||
let website_tab = window.open(); | |||||
website_tab.opener = null; | |||||
website_tab.location = "/index"; | |||||
}; | |||||
xhiveframework.ui.toolbar.setup_session_defaults = function () { | |||||
let fields = []; | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.core.doctype.session_default_settings.session_default_settings.get_session_default_values", | |||||
callback: function (data) { | |||||
fields = JSON.parse(data.message); | |||||
let perms = xhiveframework.perm.get_perm("Session Default Settings"); | |||||
//add settings button only if user is a System Manager or has permission on 'Session Default Settings' | |||||
if (in_list(xhiveframework.user_roles, "System Manager") || perms[0].read == 1) { | |||||
fields[fields.length] = { | |||||
fieldname: "settings", | |||||
fieldtype: "Button", | |||||
label: __("Settings"), | |||||
click: () => { | |||||
xhiveframework.set_route( | |||||
"Form", | |||||
"Session Default Settings", | |||||
"Session Default Settings" | |||||
); | |||||
}, | |||||
}; | |||||
} | |||||
xhiveframework.prompt( | |||||
fields, | |||||
function (values) { | |||||
//if default is not set for a particular field in prompt | |||||
fields.forEach(function (d) { | |||||
if (!values[d.fieldname]) { | |||||
values[d.fieldname] = ""; | |||||
} | |||||
}); | |||||
xhiveframework.call({ | |||||
method: "xhiveframework.core.doctype.session_default_settings.session_default_settings.set_session_default_values", | |||||
args: { | |||||
default_values: values, | |||||
}, | |||||
callback: function (data) { | |||||
if (data.message == "success") { | |||||
xhiveframework.show_alert({ | |||||
message: __("Session Defaults Saved"), | |||||
indicator: "green", | |||||
}); | |||||
xhiveframework.ui.toolbar.clear_cache(); | |||||
} else { | |||||
xhiveframework.show_alert({ | |||||
message: __( | |||||
"An error occurred while setting Session Defaults" | |||||
), | |||||
indicator: "red", | |||||
}); | |||||
} | |||||
}, | |||||
}); | |||||
}, | |||||
__("Session Defaults"), | |||||
__("Save") | |||||
); | |||||
}, | |||||
}); | |||||
}; |
@@ -0,0 +1,202 @@ | |||||
// Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||||
// MIT License. See license.txt | |||||
xhiveframework.breadcrumbs = { | |||||
all: {}, | |||||
preferred: { | |||||
"File": "", | |||||
"Dashboard": "Customization", | |||||
"Dashboard Chart": "Customization", | |||||
"Dashboard Chart Source": "Customization" | |||||
}, | |||||
module_map: { | |||||
'Core': 'Settings', | |||||
'Email': 'Settings', | |||||
'Custom': 'Settings', | |||||
'Workflow': 'Settings', | |||||
'Printing': 'Settings', | |||||
'Setup': 'Settings', | |||||
'Event Streaming': 'Tools', | |||||
'Automation': 'Tools', | |||||
}, | |||||
set_doctype_module(doctype, module) { | |||||
localStorage["preferred_breadcrumbs:" + doctype] = module; | |||||
}, | |||||
get_doctype_module(doctype) { | |||||
return localStorage["preferred_breadcrumbs:" + doctype]; | |||||
}, | |||||
add(module, doctype, type) { | |||||
let obj; | |||||
if (typeof module === 'object') { | |||||
obj = module; | |||||
} else { | |||||
obj = { | |||||
module: module, | |||||
doctype: doctype, | |||||
type: type | |||||
} | |||||
} | |||||
let breadcrumb = xhiveframework.breadcrumbs.current_page(); | |||||
breadcrumb = breadcrumb.split('/'); | |||||
this.all[xhiveframework.breadcrumbs.current_page()] = obj; | |||||
this.update(); | |||||
}, | |||||
current_page() { | |||||
return xhiveframework.get_route_str(); | |||||
}, | |||||
update() { | |||||
var breadcrumbs = this.all[xhiveframework.breadcrumbs.current_page()]; | |||||
this.clear(); | |||||
if (!breadcrumbs) return this.toggle(false); | |||||
if (breadcrumbs.type === 'Custom') { | |||||
this.set_custom_breadcrumbs(breadcrumbs); | |||||
} else { | |||||
// workspace | |||||
this.set_workspace_breadcrumb(breadcrumbs); | |||||
// form / print | |||||
let view = xhiveframework.get_route()[0]; | |||||
view = view ? view.toLowerCase() : null; | |||||
if (breadcrumbs.doctype && ["print", "form"].includes(view)) { | |||||
this.set_list_breadcrumb(breadcrumbs); | |||||
this.set_form_breadcrumb(breadcrumbs, view); | |||||
} else if (breadcrumbs.doctype && view === 'list') { | |||||
this.set_list_breadcrumb(breadcrumbs); | |||||
} | |||||
} | |||||
this.toggle(true); | |||||
}, | |||||
set_custom_breadcrumbs(breadcrumbs) { | |||||
const html = `<li><a href="${breadcrumbs.route}">${breadcrumbs.label}</a></li>`; | |||||
this.$breadcrumbs.append(html); | |||||
}, | |||||
set_workspace_breadcrumb(breadcrumbs) { | |||||
// get preferred module for breadcrumbs, based on sent via module | |||||
if (!breadcrumbs.workspace) { | |||||
this.set_workspace(breadcrumbs); | |||||
} | |||||
if (breadcrumbs.workspace) { | |||||
if (!breadcrumbs.module_info.blocked && xhiveframework.visible_modules.includes(breadcrumbs.module_info.module)) { | |||||
$(`<li><a href="/app/${xhiveframework.router.slug(breadcrumbs.workspace)}">${__(breadcrumbs.workspace)}</a></li>`) | |||||
.appendTo(this.$breadcrumbs); | |||||
} | |||||
} | |||||
}, | |||||
set_workspace(breadcrumbs) { | |||||
// try and get module from doctype or other settings | |||||
// then get the workspace for that module | |||||
this.setup_modules(); | |||||
var from_module = this.get_doctype_module(breadcrumbs.doctype); | |||||
if (from_module) { | |||||
breadcrumbs.module = from_module; | |||||
} else if (this.preferred[breadcrumbs.doctype] !== undefined) { | |||||
// get preferred module for breadcrumbs | |||||
breadcrumbs.module = this.preferred[breadcrumbs.doctype]; | |||||
} | |||||
if (breadcrumbs.module) { | |||||
if (this.module_map[breadcrumbs.module]) { | |||||
breadcrumbs.module = this.module_map[breadcrumbs.module]; | |||||
} | |||||
breadcrumbs.module_info = xhiveframework.get_module(breadcrumbs.module); | |||||
// set workspace | |||||
if (breadcrumbs.module_info && xhiveframework.boot.module_page_map[breadcrumbs.module]) { | |||||
breadcrumbs.workspace = xhiveframework.boot.module_page_map[breadcrumbs.module]; | |||||
} | |||||
} | |||||
}, | |||||
set_list_breadcrumb(breadcrumbs) { | |||||
const doctype = breadcrumbs.doctype; | |||||
const doctype_meta = xhiveframework.get_doc('DocType', doctype); | |||||
if ((doctype === "User" && !xhiveframework.user.has_role('System Manager')) | |||||
|| (doctype_meta && doctype_meta.issingle)) { | |||||
// no user listview for non-system managers and single doctypes | |||||
} else { | |||||
let route; | |||||
const doctype_route = xhiveframework.router.slug(xhiveframework.router.doctype_layout || doctype); | |||||
if (xhiveframework.boot.treeviews.indexOf(doctype) !== -1) { | |||||
let view = xhiveframework.model.user_settings[doctype].last_view || 'Tree'; | |||||
route = `${doctype_route}/view/${view}`; | |||||
} else { | |||||
route = doctype_route; | |||||
} | |||||
$(`<li><a href="/app/${route}">${__(doctype)}</a></li>`).appendTo(this.$breadcrumbs); | |||||
} | |||||
}, | |||||
set_form_breadcrumb(breadcrumbs, view) { | |||||
const doctype = breadcrumbs.doctype; | |||||
const docname = xhiveframework.get_route()[2]; | |||||
let form_route = `/app/${xhiveframework.router.slug(doctype)}/${docname}`; | |||||
$(`<li><a href="${form_route}">${this.limit_string(__(docname))}</a></li>`).appendTo(this.$breadcrumbs); | |||||
if (view === "form") { | |||||
let last_crumb = this.$breadcrumbs.find('li').last(); | |||||
last_crumb.addClass('disabled'); | |||||
last_crumb.css("cursor", "copy"); | |||||
last_crumb.click((event) => { | |||||
event.stopImmediatePropagation(); | |||||
xhiveframework.utils.copy_to_clipboard(last_crumb.text()); | |||||
}); | |||||
} | |||||
}, | |||||
setup_modules() { | |||||
if (!xhiveframework.visible_modules) { | |||||
xhiveframework.visible_modules = $.map(xhiveframework.boot.allowed_workspaces, (m) => { | |||||
return m.module; | |||||
}); | |||||
} | |||||
}, | |||||
rename(doctype, old_name, new_name) { | |||||
var old_route_str = ["Form", doctype, old_name].join("/"); | |||||
var new_route_str = ["Form", doctype, new_name].join("/"); | |||||
this.all[new_route_str] = this.all[old_route_str]; | |||||
delete xhiveframework.breadcrumbs.all[old_route_str]; | |||||
this.update(); | |||||
}, | |||||
clear() { | |||||
this.$breadcrumbs = $("#navbar-breadcrumbs").empty(); | |||||
}, | |||||
toggle(show) { | |||||
if (show) { | |||||
$("body").addClass("no-breadcrumbs"); | |||||
} else { | |||||
$("body").removeClass("no-breadcrumbs"); | |||||
} | |||||
}, | |||||
limit_string(string, limit = 25) { | |||||
if (string && string.length >= limit) { | |||||
return string.substring(0, limit) + ' ...'; | |||||
} else { | |||||
return string; | |||||
} | |||||
} | |||||
} |
@@ -0,0 +1,129 @@ | |||||
// Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||||
// MIT License. See license.txt | |||||
// page container | |||||
xhiveframework.provide("xhiveframework.pages"); | |||||
xhiveframework.provide("xhiveframework.views"); | |||||
window.cur_page = null; | |||||
xhiveframework.modules_list = []; | |||||
xhiveframework.module_items_list = []; | |||||
xhiveframework.active_module = {}; | |||||
xhiveframework.theme_settings = {}; | |||||
xhiveframework.is_app_loaded = false; | |||||
xhiveframework.is_page_changed = false; | |||||
xhiveframework.views.Container = class Container { | |||||
// Container contains pages inside `#container` and manages page creation, switching | |||||
constructor() { | |||||
this.container = $("#body").get(0); | |||||
this.page = null; // current page | |||||
this.pagewidth = $(this.container).width(); | |||||
this.pagemargin = 50; | |||||
localStorage.container_fullwidth = true; | |||||
$('body').addClass('full-width'); | |||||
var me = this; | |||||
$(document).trigger('app-loaded'); | |||||
xhiveframework.is_app_loaded = true; | |||||
document.documentElement.setAttribute("data-theme", document.documentElement.getAttribute('data-dv-theme')); | |||||
if ($('body').data('close-sub-menu') == '1') { | |||||
$('.btn-toggle-main-menu').removeClass('menu-shown'); | |||||
$('body').addClass('hide-main-menu'); | |||||
} | |||||
$(document).on("page-change", function () { | |||||
// set data-route in body | |||||
var route_str = xhiveframework.get_route_str(); | |||||
var route_obj = xhiveframework.get_route(); | |||||
let current_page = $('.content.page-container:visible', this); | |||||
$("body").attr("data-route", route_str); | |||||
$("body").attr("data-sidebar", me.has_sidebar() ? 1 : 0); | |||||
setTimeout(() => $('input#navbar-search').trigger('blur'), 250); | |||||
$('.dv-nav-search ul[role="listbox"]').prop('hidden', true); | |||||
$(document).trigger('show-side-menu'); | |||||
}); | |||||
$(document).bind("rename", function (event, dt, old_name, new_name) { | |||||
xhiveframework.breadcrumbs.rename(dt, old_name, new_name); | |||||
}); | |||||
} | |||||
add_page(label) { | |||||
var page = $('<div class="content page-container"></div>') | |||||
.attr("id", "page-" + label) | |||||
.attr("data-page-route", label) | |||||
.hide() | |||||
.appendTo(this.container) | |||||
.get(0); | |||||
page.label = label; | |||||
xhiveframework.pages[label] = page; | |||||
return page; | |||||
} | |||||
change_to(label) { | |||||
cur_page = this; | |||||
if (label.tagName) { | |||||
// if sent the div, get the table | |||||
var page = label; | |||||
} else { | |||||
var page = xhiveframework.pages[label]; | |||||
} | |||||
if (!page) { | |||||
console.log(__("Page not found") + ": " + label); | |||||
return; | |||||
} | |||||
// hide dialog | |||||
if (window.cur_dialog && cur_dialog.display && !cur_dialog.keep_open) { | |||||
if (!cur_dialog.minimizable) { | |||||
cur_dialog.hide(); | |||||
} else if (!cur_dialog.is_minimized) { | |||||
cur_dialog.toggle_minimize(); | |||||
} | |||||
} | |||||
// hide current | |||||
if (this.page && this.page != page) { | |||||
$(this.page).hide(); | |||||
$(this.page).trigger("hide"); | |||||
} | |||||
// show new | |||||
if (!this.page || this.page != page) { | |||||
this.page = page; | |||||
// $(this.page).fadeIn(300); | |||||
$(this.page).show(); | |||||
} | |||||
$(document).trigger("page-change"); | |||||
this.page._route = xhiveframework.router.get_sub_path(); | |||||
$(this.page).trigger("show"); | |||||
!this.page.disable_scroll_to_top && xhiveframework.utils.scroll_to(0); | |||||
xhiveframework.breadcrumbs.update(); | |||||
return this.page; | |||||
} | |||||
has_sidebar() { | |||||
var flag = 0; | |||||
var route_str = xhiveframework.get_route_str(); | |||||
// check in xhiveframework.ui.pages | |||||
flag = xhiveframework.ui.pages[route_str] && !xhiveframework.ui.pages[route_str].single_column; | |||||
// sometimes xhiveframework.ui.pages is updated later, | |||||
// so check the dom directly | |||||
if (!flag) { | |||||
var page_route = route_str.split("/").slice(0, 2).join("/"); | |||||
flag = $(`.page-container[data-page-route="${page_route}"] .layout-side-section`) | |||||
.length | |||||
? 1 | |||||
: 0; | |||||
} | |||||
return flag; | |||||
} | |||||
}; |
@@ -0,0 +1,425 @@ | |||||
@media (min-width: 768px) { | |||||
body.full-width .container { | |||||
width: 100% $imp; | |||||
max-width: 100% $imp; | |||||
padding: 0px 5px $imp; | |||||
} | |||||
} | |||||
.page-container { | |||||
background-color: $body_bg_color; | |||||
} | |||||
.page-head { | |||||
border-bottom: 1px solid transparent; | |||||
height: 50px; | |||||
position: relative; | |||||
top: 0px; | |||||
} | |||||
.page-head .page-head-content { | |||||
height: auto; | |||||
} | |||||
.page-head.drop-shadow { | |||||
box-shadow: none; | |||||
background-color: #fff !important; | |||||
border-bottom: 1px solid #ddd; | |||||
z-index: 150; | |||||
top: 60px; | |||||
position: sticky; | |||||
margin: 0px -20px; | |||||
padding: 10px 20px; | |||||
transition: all 0.2s ease-in-out; | |||||
} | |||||
.page-container[data-page-route="Workspaces"] { | |||||
.layout-side-section, .page-title .sidebar-toggle-btn { | |||||
display: none $imp; | |||||
} | |||||
.layout-main-section-wrapper { | |||||
width: 100% $imp; | |||||
} | |||||
} | |||||
.centered.splash { | |||||
background: #f8fafb; | |||||
position: fixed; | |||||
top: 0; | |||||
left: 0; | |||||
bottom: 0; | |||||
right: 0; | |||||
transform: inherit; | |||||
-webkit-transform: initial; | |||||
text-align: center; | |||||
vertical-align: middle; | |||||
z-index: 9999999999999999; | |||||
img { | |||||
position: absolute; | |||||
left: 50%; | |||||
top: 50%; | |||||
margin: -50px 0px 0px -50px; | |||||
} | |||||
} | |||||
@media (min-width: 992px) { | |||||
[data-page-route="Workspaces"] .layout-main { | |||||
height: auto; | |||||
} | |||||
} | |||||
@media (min-width: 992px) { | |||||
[data-page-route="Workspaces"] .layout-main .layout-side-section, [data-page-route="Workspaces"] .layout-main .layout-main-section-wrapper { | |||||
height: auto; | |||||
padding-right: 20px; | |||||
padding-left: 20px; | |||||
} | |||||
} | |||||
.list-sidebar .list-filters input { | |||||
background: #ffffff; | |||||
border: 1px solid #d0d0d0; | |||||
} | |||||
.awesomplete .input-with-feedback { | |||||
background-color: #ffffff; | |||||
border: 1px solid #bbb; | |||||
} | |||||
.btn { | |||||
box-shadow: none $imp; | |||||
transition: all 0.2s ease-in-out; | |||||
border-radius: 5px; | |||||
} | |||||
.form-control { | |||||
background: #ffffff; | |||||
border: 1px solid #bbb; | |||||
transition: all 0.2s ease-in-out; | |||||
box-shadow: inset 1px 1px 7px -4px rgba(0, 0, 0, 0.44) $imp; | |||||
border-radius: 5px; | |||||
&:hover { | |||||
border-color: #999999; | |||||
} | |||||
&:focus { | |||||
background: #ffffff $imp; | |||||
border-color: var(--primary) $imp; | |||||
box-shadow: inset 1px 1px 7px -4px rgba(0, 0, 0, 0.44), 0 4px 24px 0 rgba(34, 41, 47, 0.10) $imp; | |||||
} | |||||
} | |||||
.btn.btn-default { | |||||
border: 1px solid #d1d3d8 $imp; | |||||
&:hover { | |||||
background: rgba(235, 239, 243, 0.7) $imp; | |||||
border-color: #a2a8b1 $imp; | |||||
} | |||||
} | |||||
.page-head { | |||||
.primary-action { | |||||
.icon { | |||||
display: none $imp; | |||||
} | |||||
span.hidden-xs { | |||||
display: inline-block $imp; | |||||
} | |||||
} | |||||
} | |||||
.page-form { | |||||
border-bottom: 1px solid #efefef; | |||||
} | |||||
select.input-xs { | |||||
line-height: 14px; | |||||
padding: 0 12px; | |||||
cursor: pointer; | |||||
} | |||||
input[type="radio"], input[type="checkbox"] { | |||||
cursor: pointer; | |||||
} | |||||
button.btn.btn-default.btn-sm.btn-paging.btn-info { | |||||
background: #14a6ef $imp; | |||||
border-color: #14a6ef $imp; | |||||
color: #fff $imp; | |||||
} | |||||
.xhiveframework-list { | |||||
padding: 0px $imp; | |||||
} | |||||
.list-row-head { | |||||
background: #f3f3f5; | |||||
border-bottom: 1px solid #e8e8e8; | |||||
cursor: default; | |||||
font-size: 16px; | |||||
font-weight: 600; | |||||
} | |||||
.report-summary .summary-value { | |||||
height: auto; | |||||
min-height: 30px; | |||||
} | |||||
.alert.desk-alert { | |||||
.dv-alert-icon { | |||||
margin: 0px; | |||||
} | |||||
&.dv-alert-success, &.dv-alert-green { | |||||
border: 1px solid var(--success); | |||||
} | |||||
&.dv-alert-info, &.dv-alert-blue { | |||||
border: 1px solid var(--info); | |||||
} | |||||
&.dv-alert-error, &.dv-alert-red { | |||||
border: 1px solid var(--danger); | |||||
} | |||||
&.dv-alert-warning, &.dv-alert-orange, &.dv-alert-yellow { | |||||
border: 1px solid var(--orange); | |||||
} | |||||
} | |||||
.alert-body { | |||||
text-align: left; | |||||
padding: 0px 15px 10px 15px; | |||||
} | |||||
.btn svg.icon.icon-sm { | |||||
position: relative; | |||||
top: -1px; | |||||
} | |||||
.layout-main { | |||||
position: relative; | |||||
.btn-toggle-sidebar { | |||||
background: #fff; | |||||
border: 0; | |||||
box-shadow: -2px 0px 5px -2px #00000030; | |||||
margin: 0px 15px 0px 0px; | |||||
height: 30px; | |||||
width: 20px; | |||||
display: none; | |||||
text-align: center; | |||||
line-height: 29px; | |||||
font-size: 16px; | |||||
padding: 0; | |||||
position: absolute; | |||||
left: 0px; | |||||
top: 0px; | |||||
z-index: 50; | |||||
color: #666666; | |||||
border-radius: 5px 0px 0px 5px; | |||||
transition: all 0.2s ease-in; | |||||
&.sidebar-shown { | |||||
> i { | |||||
display: inline-block; | |||||
transform: rotate(180deg); | |||||
} | |||||
} | |||||
&:hover { | |||||
color: #434346; | |||||
} | |||||
} | |||||
} | |||||
.sidebar-toggle-btn { | |||||
display: none $imp; | |||||
} | |||||
.btn-toggle-main-menu { | |||||
background: $my_color; | |||||
border: 0px; | |||||
margin: 0px 15px 0px 0px; | |||||
height: 30px; | |||||
width: 30px; | |||||
min-width: 30px; | |||||
display: inline-block; | |||||
text-align: center; | |||||
line-height: 30px; | |||||
font-size: 16px; | |||||
padding: 0; | |||||
color: #ffffff; | |||||
border-radius: 5px; | |||||
transition: all 0.2s ease-in; | |||||
&:hover { | |||||
background: $my_color_hover; | |||||
} | |||||
} | |||||
.page-form .filter-button.btn-primary-light { | |||||
color: #000000; | |||||
} | |||||
.filter-icon.active use { | |||||
stroke: #000000; | |||||
} | |||||
.layout-main-section-wrapper { | |||||
margin-bottom: 0; | |||||
} | |||||
.widget .widget-head .widget-label .widget-title { | |||||
font-weight: 600; | |||||
} | |||||
.widget.shortcut-widget-box { | |||||
border: 1px solid #ddd; | |||||
box-shadow: 0px 3px 10px -5px rgba(0, 0, 0, .20); | |||||
border-radius: 6px; | |||||
padding: 10px 12px; | |||||
transition: all 0.2s ease-in-out; | |||||
.widget-title { | |||||
transition: all 0.2s ease-in-out; | |||||
} | |||||
& ~ .divider { | |||||
display: none; | |||||
} | |||||
&:hover { | |||||
border-color: var(--blue-500); | |||||
.widget-title { | |||||
color: var(--blue-500) !important; | |||||
} | |||||
} | |||||
} | |||||
.widget.dashboard-widget-box, .number-widget-box { | |||||
border: 1px solid #ddd; | |||||
box-shadow: 0px 3px 10px -5px rgba(0, 0, 0, .20); | |||||
} | |||||
.widget.links-widget-box { | |||||
border: 1px solid #ddd; | |||||
box-shadow: 0px 3px 10px -5px rgba(0, 0, 0, .20); | |||||
.widget-head { | |||||
border-bottom: 1px solid #ddd; | |||||
padding: 8px 15px 10px 15px; | |||||
margin: -13px -13px -8px -13px; | |||||
} | |||||
.link-item { | |||||
font-weight: 600; | |||||
} | |||||
} | |||||
.layout-main-section .xhiveframework-list .result, .layout-main-section .xhiveframework-list .no-result, .layout-main-section .xhiveframework-list .freeze, .layout-main-section .report-wrapper .result, .layout-main-section .report-wrapper .no-result, .layout-main-section .report-wrapper .freeze { | |||||
min-height: calc(100vh - 295px); | |||||
} | |||||
.theme-setting-colors-select { | |||||
margin: 0px; | |||||
> h4 { | |||||
font-weight: 600; | |||||
margin-bottom: 15px; | |||||
} | |||||
button { | |||||
background: #aaaaaa; | |||||
border: 0px; | |||||
outline: none; | |||||
width: 100%; | |||||
height: 65px; | |||||
text-align: center; | |||||
line-height: 65px; | |||||
color: #ffffff; | |||||
border-radius: 5px; | |||||
transition: all 0.2s ease-in-out; | |||||
&.active { | |||||
position: relative; | |||||
box-shadow: inset 0px 0px 5px rgba(0, 0, 0, 0.45); | |||||
&:after { | |||||
content: "\f058"; | |||||
font-family: "Font Awesome 5 Pro"; | |||||
font-weight: 700; | |||||
font-size: 18px; | |||||
position: absolute; | |||||
line-height: 26px; | |||||
top: 0px; | |||||
right: 5px; | |||||
} | |||||
} | |||||
&[data-color="Blue"] { | |||||
background: $my_color; | |||||
} | |||||
&[data-color="Green"] { | |||||
background: $green_color_style; | |||||
} | |||||
&[data-color="Red"] { | |||||
background: $red_color_style; | |||||
} | |||||
&[data-color="Orange"] { | |||||
background: $orange_color_style; | |||||
} | |||||
&[data-color="Yellow"] { | |||||
background: $yellow_color_style; | |||||
} | |||||
&[data-color="Pink"] { | |||||
background: $pink_color_style; | |||||
} | |||||
&[data-color="Violet"] { | |||||
background: $violet_color_style; | |||||
} | |||||
} | |||||
} | |||||
.form-tabs-sticky-down { | |||||
top: calc(var(--navbar-height) + var(--page-head-height) - 25px) $imp; | |||||
} | |||||
.xhiveframework-control[data-fieldtype=Icon] .selected-icon { | |||||
top: calc(50% + -1px); | |||||
font-size: 18px; | |||||
} | |||||
.icon-picker .icons .icon-wrapper { | |||||
font-size: 20px; | |||||
opacity: .8; | |||||
color: #444; | |||||
border: 1px solid #aaa; | |||||
border-radius: 4px; | |||||
margin: 2.4px 2px; | |||||
transition: all 0.2s ease-in-out; | |||||
&:hover { | |||||
border-color: #444444; | |||||
color: #000000; | |||||
opacity: 1; | |||||
} | |||||
> i { | |||||
display: block; | |||||
margin: 0px auto; | |||||
} | |||||
} |