@@ -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; | |||
} | |||
} |