@@ -1,7 +1,7 @@ | |||
## Datavalue Theme 14 | |||
Data Value Frappe 14 Theme | |||
Data Value Xhiveframework 14 Theme | |||
#### License | |||
MIT | |||
MIT |
@@ -1,18 +1,18 @@ | |||
from __future__ import unicode_literals | |||
import frappe | |||
from frappe import _ | |||
from frappe.cache_manager import clear_user_cache | |||
import xhiveframework | |||
from xhiveframework import _ | |||
from xhiveframework.cache_manager import clear_user_cache | |||
@frappe.whitelist() | |||
@xhiveframework.whitelist() | |||
def get_module_name_from_doctype(doc_name, current_module=""): | |||
# frappe.msgprint("======"+str(doc_name)) | |||
# xhiveframework.msgprint("======"+str(doc_name)) | |||
condition = "" | |||
if doc_name: | |||
if current_module: | |||
condition = "and w.`name` = {current_module} ".format(current_module=current_module) | |||
list_od_dicts = frappe.db.sql(""" | |||
list_od_dicts = xhiveframework.db.sql(""" | |||
select * | |||
from ( | |||
select w.`name` `module`, | |||
@@ -28,7 +28,7 @@ def get_module_name_from_doctype(doc_name, current_module=""): | |||
if list_od_dicts: | |||
return [{"module": list_od_dicts[0]["module"]}] | |||
else: | |||
list_od_dicts = frappe.db.sql(""" | |||
list_od_dicts = xhiveframework.db.sql(""" | |||
select * | |||
from ( | |||
select w.`name` `module`, | |||
@@ -44,33 +44,33 @@ def get_module_name_from_doctype(doc_name, current_module=""): | |||
return [{"module": list_od_dicts[0]["module"]}] | |||
@frappe.whitelist() | |||
@xhiveframework.whitelist() | |||
def change_language(language): | |||
frappe.db.set_value("User", frappe.session.user, "language", language) | |||
xhiveframework.db.set_value("User", xhiveframework.session.user, "language", language) | |||
clear() | |||
return True | |||
@frappe.whitelist() | |||
@xhiveframework.whitelist() | |||
def get_current_language(): | |||
return frappe.db.get_value("User", frappe.session.user, "language") | |||
return xhiveframework.db.get_value("User", xhiveframework.session.user, "language") | |||
@frappe.whitelist() | |||
@xhiveframework.whitelist() | |||
def get_company_logo(): | |||
logo_path = "" | |||
current_company = frappe.defaults.get_user_default("company") | |||
current_company = xhiveframework.defaults.get_user_default("company") | |||
if current_company: | |||
logo_path = frappe.db.get_value("Company", current_company, "company_logo") | |||
logo_path = xhiveframework.db.get_value("Company", current_company, "company_logo") | |||
return logo_path | |||
@frappe.whitelist(allow_guest=True) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def get_theme_settings(): | |||
slideshow_photos = [] | |||
settings_list = {} | |||
settings = frappe.db.sql(""" | |||
settings = xhiveframework.db.sql(""" | |||
SELECT * FROM tabSingles WHERE doctype = 'Theme Settings'; | |||
""", as_dict=True, debug=False) | |||
@@ -78,7 +78,7 @@ def get_theme_settings(): | |||
settings_list[setting['field']] = setting['value'] | |||
if (("background_type" in settings_list) and settings_list['background_type'] == 'Slideshow'): | |||
slideshow_photos = frappe.db.sql(""" | |||
slideshow_photos = xhiveframework.db.sql(""" | |||
SELECT `photo` FROM `tabSlideshow Photos` WHERE `parent` = 'Theme Settings'; | |||
""", as_dict=True, debug=False) | |||
@@ -99,7 +99,7 @@ def get_theme_settings(): | |||
} | |||
def clear(): | |||
frappe.local.session_obj.update(force=True) | |||
frappe.local.db.commit() | |||
clear_user_cache(frappe.session.user) | |||
frappe.response['message'] = _("Cache Cleared") | |||
xhiveframework.local.session_obj.update(force=True) | |||
xhiveframework.local.db.commit() | |||
clear_user_cache(xhiveframework.session.user) | |||
xhiveframework.response['message'] = _("Cache Cleared") |
@@ -1,4 +1,4 @@ | |||
from frappe import _ | |||
from xhiveframework import _ | |||
def get_data(): | |||
return [ | |||
@@ -1,8 +1,8 @@ | |||
# Copyright (c) 2021, Abdo Hamoud and contributors | |||
# For license information, please see license.txt | |||
# import frappe | |||
from frappe.model.document import Document | |||
# import xhiveframework | |||
from xhiveframework.model.document import Document | |||
class SlideshowPhotos(Document): | |||
pass |
@@ -1,7 +1,7 @@ | |||
# Copyright (c) 2021, Abdo Hamoud and Contributors | |||
# See license.txt | |||
# import frappe | |||
# import xhiveframework | |||
import unittest | |||
class TestThemeSettings(unittest.TestCase): | |||
@@ -1,11 +1,11 @@ | |||
// Copyright (c) 2021, Abdo Hamoud and contributors | |||
// For license information, please see license.txt | |||
frappe.ui.form.on('Theme Settings', { | |||
xhiveframework.ui.form.on('Theme Settings', { | |||
refresh: function (frm) { | |||
$('[data-fieldname="font_family"] select').chosen({width: '50%'}) | |||
}, | |||
after_save: function (frm) { | |||
setTimeout(() => frappe.ui.toolbar.clear_cache(), 500); | |||
setTimeout(() => xhiveframework.ui.toolbar.clear_cache(), 500); | |||
} | |||
}); |
@@ -1,7 +1,7 @@ | |||
{ | |||
"actions": [ | |||
{ | |||
"action": "frappe.sessions.clear", | |||
"action": "xhiveframework.sessions.clear", | |||
"action_type": "Server Action", | |||
"label": "Clear Cache" | |||
} | |||
@@ -178,4 +178,4 @@ | |||
"sort_field": "modified", | |||
"sort_order": "DESC", | |||
"states": [] | |||
} | |||
} |
@@ -1,8 +1,8 @@ | |||
# Copyright (c) 2021, Abdo Hamoud and contributors | |||
# For license information, please see license.txt | |||
# import frappe | |||
from frappe.model.document import Document | |||
# import xhiveframework | |||
from xhiveframework.model.document import Document | |||
class ThemeSettings(Document): | |||
pass |
@@ -3,7 +3,7 @@ from . import __version__ as app_version | |||
app_name = "datavalue_theme_14" | |||
app_title = "Datavalue Theme 14" | |||
app_publisher = "Abdo Hamoud" | |||
app_description = "Data Value Frappe 14 Theme" | |||
app_description = "Data Value Xhiveframework 14 Theme" | |||
app_email = "abdo.host@gmail.com" | |||
app_license = "MIT" | |||
@@ -108,7 +108,7 @@ web_include_js = [ | |||
# Desk Notifications | |||
# ------------------ | |||
# See frappe.core.notifications.get_notification_config | |||
# See xhiveframework.core.notifications.get_notification_config | |||
# notification_config = "datavalue_theme_14.notifications.get_notification_config" | |||
@@ -117,11 +117,11 @@ web_include_js = [ | |||
# Permissions evaluated in scripted ways | |||
# permission_query_conditions = { | |||
# "Event": "frappe.desk.doctype.event.event.get_permission_query_conditions", | |||
# "Event": "xhiveframework.desk.doctype.event.event.get_permission_query_conditions", | |||
# } | |||
# | |||
# has_permission = { | |||
# "Event": "frappe.desk.doctype.event.event.has_permission", | |||
# "Event": "xhiveframework.desk.doctype.event.event.has_permission", | |||
# } | |||
# DocType Class | |||
@@ -174,12 +174,12 @@ web_include_js = [ | |||
# ------------------------------ | |||
# | |||
# override_whitelisted_methods = { | |||
# "frappe.desk.doctype.event.event.get_events": "datavalue_theme_14.event.get_events" | |||
# "xhiveframework.desk.doctype.event.event.get_events": "datavalue_theme_14.event.get_events" | |||
# } | |||
# | |||
# each overriding function accepts a `data` argument; | |||
# generated from the base implementation of the doctype dashboard, | |||
# along with any modifications made in other Frappe apps | |||
# along with any modifications made in other Xhiveframework apps | |||
# override_doctype_dashboards = { | |||
# "Task": "datavalue_theme_14.task.get_dashboard_data" | |||
# } | |||
@@ -1,12 +0,0 @@ | |||
<?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="frappe" 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> |
@@ -1,4 +1,4 @@ | |||
<svg id="frappe-symbols" aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" class="d-block" xmlns="http://www.w3.org/2000/svg"> | |||
<svg id="xhiveframework-symbols" aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" class="d-block" xmlns="http://www.w3.org/2000/svg"> | |||
<symbol viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" id="icon-up-line"> | |||
<path d="M13 10.5L8 5.5L3 10.5" stroke="var(--icon-stroke)" stroke-linecap="round" stroke-linejoin="round"/> | |||
</symbol> | |||
@@ -1,4 +1,4 @@ | |||
<svg id="frappe-symbols" aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" class="d-block" xmlns="http://www.w3.org/2000/svg"> | |||
<svg id="xhiveframework-symbols" aria-hidden="true" style="position: absolute; width: 0; height: 0; overflow: hidden;" class="d-block" xmlns="http://www.w3.org/2000/svg"> | |||
<symbol viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg" id="icon-resting"> | |||
<path d="M7.606 3.799L8 4.302l.394-.503.106-.14c.048-.065.08-.108.129-.159a3.284 3.284 0 0 1 4.72 0c.424.434.655 1.245.65 2.278-.006 1.578-.685 2.931-1.728 4.159-1.05 1.234-2.439 2.308-3.814 3.328a.763.763 0 0 1-.914 0c-1.375-1.02-2.764-2.094-3.814-3.328C2.686 8.709 2.007 7.357 2 5.778c-.004-1.033.227-1.844.651-2.278a3.284 3.284 0 0 1 4.72 0c.05.05.081.094.129.158.028.038.061.083.106.14z" | |||
stroke="var(--icon-stroke)"></path> | |||
@@ -567,7 +567,7 @@ | |||
<path d="M6.45466 8.81824L4.47873 10.7942C3.85205 11.4211 3.5 12.2713 3.5 13.1577C3.5 14.0442 3.85205 14.8943 4.47873 15.5213V15.5213C5.10568 16.148 5.95584 16.5 6.84229 16.5C7.72874 16.5 8.5789 16.148 9.20584 15.5213L11.1818 13.5453" stroke="var(--icon-stroke)" stroke-linecap="round" stroke-linejoin="round"/> | |||
</symbol> | |||
<symbol viewBox="0 0 24 24" fill="none" id="icon-scan" xmlns="http://www.w3.org/2000/svg"> | |||
<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" | |||
<path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" | |||
stroke="var(--icon-stroke)" stroke-linecap="round" stroke-linejoin="round" stroke-width="1.5"/> | |||
</symbol> | |||
<symbol viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" id="icon-dashboard"> | |||
@@ -1,4 +1,4 @@ | |||
frappe.ui.form.on("File", { | |||
xhiveframework.ui.form.on("File", { | |||
onload: function (frm) { | |||
}, | |||
@@ -6,7 +6,7 @@ frappe.ui.form.on("File", { | |||
let wrapper = frm.get_field("preview_html").$wrapper; | |||
let selected_doc = frm.selected_doc; | |||
let file_ext = (selected_doc.file_name) ? selected_doc.file_name.split('.').pop() : ''; | |||
let is_viewable = (file_ext && file_ext.toLowerCase() == 'pdf') ? true : frappe.utils.is_image_file(frm.doc.file_url); | |||
let is_viewable = (file_ext && file_ext.toLowerCase() == 'pdf') ? true : xhiveframework.utils.is_image_file(frm.doc.file_url); | |||
frm.toggle_display("preview", is_viewable); | |||
frm.toggle_display("preview_html", is_viewable); | |||
console.log(frm) | |||
@@ -21,7 +21,7 @@ frappe.ui.form.on("File", { | |||
<embed style="background:#323639;" width="100%" height="1190" src="${frm.doc.file_url}" type="application/pdf"> | |||
</object> | |||
</div>`); | |||
} else if (frappe.utils.is_image_file(frm.doc.file_url)) { | |||
} else if (xhiveframework.utils.is_image_file(frm.doc.file_url)) { | |||
wrapper.html(`<div class="img_preview"> | |||
<img class="img-responsive" src="${frm.doc.file_url}"> | |||
</div>`); | |||
@@ -1,10 +1,10 @@ | |||
import "./frappe/ui/page.html"; | |||
import "./frappe/ui/page.js"; | |||
import "./frappe/views/container.js"; | |||
import "./frappe/views/breadcrumbs.js"; | |||
import "./frappe/ui/toolbar/toolbar.js"; | |||
import "./frappe/ui/toolbar/navbar.html"; | |||
import "./frappe/ui/notifications/notifications.js"; | |||
import "./frappe/form/controls/icon.js"; | |||
import "./xhiveframework/ui/page.html"; | |||
import "./xhiveframework/ui/page.js"; | |||
import "./xhiveframework/views/container.js"; | |||
import "./xhiveframework/views/breadcrumbs.js"; | |||
import "./xhiveframework/ui/toolbar/toolbar.js"; | |||
import "./xhiveframework/ui/toolbar/navbar.html"; | |||
import "./xhiveframework/ui/notifications/notifications.js"; | |||
import "./xhiveframework/form/controls/icon.js"; | |||
import "./vue/side-menu.js"; | |||
import "./frappe/ui/toolbar/theme-setting.js"; | |||
import "./xhiveframework/ui/toolbar/theme-setting.js"; |
@@ -63,7 +63,7 @@ | |||
// files icon | |||
$(this).on('click', '.dv-navbar .files-icon', function (event) { | |||
event.preventDefault(); | |||
frappe.set_route("List", "File"); | |||
xhiveframework.set_route("List", "File"); | |||
}); | |||
// files icon | |||
$(this).on('click', '.dv-navbar .full-screen-icon', function (event) { | |||
@@ -85,14 +85,14 @@ | |||
let language = $this.data('lang'); | |||
let selected_flag = $this.find(".dv-lang-flag").attr("class"); | |||
$("#header-navbar-change-lang .dropdown-lang-link").html(`<span class="${selected_flag}"></span> ${language}`); | |||
frappe.call({ | |||
xhiveframework.call({ | |||
method: "datavalue_theme_14.api.change_language", | |||
args: { | |||
language: language.toLowerCase() | |||
}, | |||
callback: function (r) { | |||
localStorage.setItem("active_lang", language); | |||
frappe.ui.toolbar.clear_cache(); | |||
xhiveframework.ui.toolbar.clear_cache(); | |||
} | |||
}); | |||
}); | |||
@@ -170,7 +170,7 @@ | |||
$(document).on("app-loaded", function () { | |||
if (frappe.is_app_loaded) | |||
if (xhiveframework.is_app_loaded) | |||
return; | |||
let AppLogoVM = new Vue({ | |||
@@ -184,7 +184,7 @@ | |||
methods: { | |||
get_company_logo: function () { | |||
const $this = this; | |||
frappe.call({ | |||
xhiveframework.call({ | |||
type: 'POST', | |||
method: 'datavalue_theme_14.api.get_company_logo', | |||
args: {}, | |||
@@ -204,7 +204,7 @@ | |||
await this.get_company_logo(); | |||
}, | |||
created: function () { | |||
this.user = frappe.get_cookies(); | |||
this.user = xhiveframework.get_cookies(); | |||
} | |||
}); | |||
@@ -216,8 +216,8 @@ | |||
user_type: '' | |||
}, | |||
created: function () { | |||
this.user = frappe.get_cookies(); | |||
frappe.db.get_value('User', this.user.user_id, 'user_type', (response) => { | |||
this.user = xhiveframework.get_cookies(); | |||
xhiveframework.db.get_value('User', this.user.user_id, 'user_type', (response) => { | |||
if (this.user.user_id == 'Administrator') { | |||
this.user_type = __('Administrator'); | |||
} else { | |||
@@ -247,7 +247,7 @@ | |||
methods: { | |||
get_current_language: function () { | |||
const $this = this; | |||
frappe.call({ | |||
xhiveframework.call({ | |||
method: "datavalue_theme_14.api.get_current_language", | |||
args: {}, | |||
callback: function (response) { | |||
@@ -1,656 +0,0 @@ | |||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt | |||
/* eslint-disable no-console */ | |||
// __('Modules') __('Domains') __('Places') __('Administration') # for translation, don't remove | |||
frappe.start_app = function () { | |||
if (!frappe.Application) return; | |||
frappe.assets.check(); | |||
frappe.provide("frappe.app"); | |||
frappe.provide("frappe.desk"); | |||
frappe.app = new frappe.Application(); | |||
}; | |||
$(document).ready(function () { | |||
if (!frappe.utils.supportsES6) { | |||
frappe.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." | |||
), | |||
}); | |||
} | |||
frappe.start_app(); | |||
}); | |||
frappe.Application = class Application { | |||
constructor() { | |||
this.startup(); | |||
} | |||
startup() { | |||
frappe.socketio.init(); | |||
frappe.model.init(); | |||
if (frappe.boot.status === "failed") { | |||
frappe.msgprint({ | |||
message: frappe.boot.error, | |||
title: __("Session Start Failed"), | |||
indicator: "red", | |||
}); | |||
throw "boot failed"; | |||
} | |||
this.setup_frappe_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(); | |||
frappe.ui.keys.setup(); | |||
frappe.ui.keys.add_shortcut({ | |||
shortcut: "shift+ctrl+g", | |||
description: __("Switch Theme"), | |||
action: () => { | |||
if (frappe.theme_switcher && frappe.theme_switcher.dialog.is_visible) { | |||
frappe.theme_switcher.hide(); | |||
} else { | |||
frappe.theme_switcher = new frappe.ui.ThemeSwitcher(); | |||
frappe.theme_switcher.show(); | |||
} | |||
}, | |||
}); | |||
frappe.ui.add_system_theme_switch_listener(); | |||
const root = document.documentElement; | |||
// const observer = new MutationObserver(() => { | |||
// frappe.ui.set_theme(); | |||
// }); | |||
// observer.observe(root, { | |||
// attributes: true, | |||
// attributeFilter: ["data-theme-mode"], | |||
// }); | |||
frappe.ui.set_theme(); | |||
// page container | |||
this.make_page_container(); | |||
this.set_route(); | |||
// trigger app startup | |||
$(document).trigger("startup"); | |||
$(document).trigger("app_ready"); | |||
if (frappe.boot.messages) { | |||
frappe.msgprint(frappe.boot.messages); | |||
} | |||
if (frappe.user_roles.includes("System Manager")) { | |||
// delayed following requests to make boot faster | |||
setTimeout(() => { | |||
this.show_change_log(); | |||
this.show_update_available(); | |||
}, 1000); | |||
} | |||
if (!frappe.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 (frappe.ui.startup_setup_dialog && !frappe.boot.setup_complete) { | |||
frappe.ui.startup_setup_dialog.pre_show(); | |||
frappe.ui.startup_setup_dialog.show(); | |||
} | |||
frappe.realtime.on("version-update", function () { | |||
var dialog = frappe.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 (frappe.sys_defaults.email_user_password) { | |||
var email_list = frappe.sys_defaults.email_user_password.split(","); | |||
for (var u in email_list) { | |||
if (email_list[u] === frappe.user.name) { | |||
this.set_password(email_list[u]); | |||
} | |||
} | |||
} | |||
// REDESIGN-TODO: Fix preview popovers | |||
this.link_preview = new frappe.ui.LinkPreview(); | |||
if (!frappe.boot.developer_mode) { | |||
if (frappe.user.has_role("System Manager")) { | |||
setInterval(function () { | |||
frappe.call({ | |||
method: "frappe.core.doctype.log_settings.log_settings.has_unseen_error_log", | |||
args: { | |||
user: frappe.session.user, | |||
}, | |||
callback: function (r) { | |||
if (r.message.show_alert) { | |||
frappe.show_alert({ | |||
indicator: "red", | |||
message: r.message.message, | |||
}); | |||
} | |||
}, | |||
}); | |||
}, 600000); // check every 10 minutes | |||
} | |||
} | |||
} | |||
set_route() { | |||
frappe.flags.setting_original_route = true; | |||
if (frappe.boot && localStorage.getItem("session_last_route")) { | |||
frappe.set_route(localStorage.getItem("session_last_route")); | |||
localStorage.removeItem("session_last_route"); | |||
} else { | |||
// route to home page | |||
frappe.router.route(); | |||
} | |||
frappe.after_ajax(() => (frappe.flags.setting_original_route = false)); | |||
frappe.router.on("change", () => { | |||
$(".tooltip").hide(); | |||
}); | |||
} | |||
setup_frappe_vue() { | |||
Vue.prototype.__ = window.__; | |||
Vue.prototype.frappe = window.frappe; | |||
} | |||
set_password(user) { | |||
var me = this; | |||
frappe.call({ | |||
method: "frappe.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 frappe.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 frappe.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(); | |||
frappe.call({ | |||
method: "frappe.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"]) { | |||
frappe.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 (frappe.boot) { | |||
this.setup_workspaces(); | |||
frappe.model.sync(frappe.boot.docs); | |||
this.check_metadata_cache_status(); | |||
this.set_globals(); | |||
this.sync_pages(); | |||
frappe.router.setup(); | |||
this.setup_moment(); | |||
if (frappe.boot.print_css) { | |||
frappe.dom.set_style(frappe.boot.print_css, "print-style"); | |||
} | |||
frappe.user.name = frappe.boot.user.name; | |||
frappe.router.setup(); | |||
} else { | |||
this.set_as_guest(); | |||
} | |||
} | |||
setup_workspaces() { | |||
frappe.modules = {}; | |||
frappe.workspaces = {}; | |||
for (let page of frappe.boot.allowed_workspaces || []) { | |||
frappe.modules[page.module] = page; | |||
frappe.workspaces[frappe.router.slug(page.name)] = page; | |||
} | |||
} | |||
load_user_permissions() { | |||
frappe.defaults.update_user_permissions(); | |||
frappe.realtime.on( | |||
"update_user_permissions", | |||
frappe.utils.debounce(() => { | |||
frappe.defaults.update_user_permissions(); | |||
}, 500) | |||
); | |||
} | |||
check_metadata_cache_status() { | |||
if (frappe.boot.metadata_version != localStorage.metadata_version) { | |||
frappe.assets.clear_local_storage(); | |||
frappe.assets.init_local_storage(); | |||
} | |||
} | |||
set_globals() { | |||
frappe.session.user = frappe.boot.user.name; | |||
frappe.session.logged_in_user = frappe.boot.user.name; | |||
frappe.session.user_email = frappe.boot.user.email; | |||
frappe.session.user_fullname = frappe.user_info().fullname; | |||
frappe.user_defaults = frappe.boot.user.defaults; | |||
frappe.user_roles = frappe.boot.user.roles; | |||
frappe.sys_defaults = frappe.boot.sysdefaults; | |||
frappe.ui.py_date_format = frappe.boot.sysdefaults.date_format | |||
.replace("dd", "%d") | |||
.replace("mm", "%m") | |||
.replace("yyyy", "%Y"); | |||
frappe.boot.user.last_selected_values = {}; | |||
} | |||
sync_pages() { | |||
// clear cached pages if timestamp is not found | |||
if (localStorage["page_info"]) { | |||
frappe.boot.allowed_pages = []; | |||
var page_info = JSON.parse(localStorage["page_info"]); | |||
$.each(frappe.boot.page_info, function (name, p) { | |||
if (!page_info[name] || page_info[name].modified != p.modified) { | |||
delete localStorage["_page:" + name]; | |||
} | |||
frappe.boot.allowed_pages.push(name); | |||
}); | |||
} else { | |||
frappe.boot.allowed_pages = Object.keys(frappe.boot.page_info); | |||
} | |||
localStorage["page_info"] = JSON.stringify(frappe.boot.page_info); | |||
} | |||
set_as_guest() { | |||
frappe.session.user = "Guest"; | |||
frappe.session.user_email = ""; | |||
frappe.session.user_fullname = "Guest"; | |||
frappe.user_defaults = {}; | |||
frappe.user_roles = ["Guest"]; | |||
frappe.sys_defaults = {}; | |||
} | |||
make_page_container() { | |||
if ($("#body").length) { | |||
$(".splash").remove(); | |||
frappe.temp_container = $("<div id='temp-container' style='display: none;'>").appendTo( | |||
"body" | |||
); | |||
frappe.container = new frappe.views.Container(); | |||
} | |||
} | |||
make_nav_bar() { | |||
// toolbar | |||
if (frappe.boot && frappe.boot.home_page !== "setup-wizard") { | |||
frappe.frappe_toolbar = new frappe.ui.toolbar.Toolbar(); | |||
} | |||
} | |||
logout() { | |||
var me = this; | |||
me.logged_out = true; | |||
return frappe.call({ | |||
method: "logout", | |||
callback: function (r) { | |||
if (r.exc) { | |||
return; | |||
} | |||
me.redirect_to_login(); | |||
}, | |||
}); | |||
} | |||
handle_session_expired() { | |||
if (!frappe.app.session_expired_dialog) { | |||
var dialog = new frappe.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) { | |||
frappe.app.redirect_to_login(); | |||
} | |||
}, | |||
}); | |||
dialog.set_primary_action(__("Login"), () => { | |||
dialog.set_message(__("Authenticating...")); | |||
frappe.call({ | |||
method: "login", | |||
args: { | |||
usr: frappe.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(); | |||
}, | |||
}); | |||
}); | |||
frappe.app.session_expired_dialog = dialog; | |||
} | |||
if (!frappe.app.session_expired_dialog.display) { | |||
frappe.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 (frappe.container.page.save_action) { | |||
frappe.container.page.save_action(); | |||
} | |||
}, 100); | |||
} | |||
show_change_log() { | |||
var me = this; | |||
let change_log = frappe.boot.change_log; | |||
// frappe.boot.change_log = [{ | |||
// "change_log": [ | |||
// [<version>, <change_log in markdown>], | |||
// [<version>, <change_log in markdown>], | |||
// ], | |||
// "description": "ERP made simple", | |||
// "title": "ERPNext", | |||
// "version": "12.2.0" | |||
// }]; | |||
if ( | |||
!Array.isArray(change_log) || | |||
!change_log.length || | |||
window.Cypress || | |||
cint(frappe.boot.sysdefaults.disable_change_log_notification) | |||
) { | |||
return; | |||
} | |||
// Iterate over changelog | |||
var change_log_dialog = frappe.msgprint({ | |||
message: frappe.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 () { | |||
frappe.call({ | |||
method: "frappe.utils.change_log.update_last_known_versions", | |||
}); | |||
me.show_notes(); | |||
}; | |||
} | |||
show_update_available() { | |||
if (frappe.boot.sysdefaults.disable_system_update_notification) return; | |||
frappe.call({ | |||
method: "frappe.utils.change_log.show_update_popup", | |||
}); | |||
} | |||
setup_analytics() { | |||
if (window.mixpanel) { | |||
window.mixpanel.identify(frappe.session.user); | |||
window.mixpanel.people.set({ | |||
$first_name: frappe.boot.user.first_name, | |||
$last_name: frappe.boot.user.last_name, | |||
$created: frappe.boot.user.creation, | |||
$email: frappe.session.user, | |||
}); | |||
} | |||
} | |||
add_browser_class() { | |||
$("html").addClass(frappe.utils.get_browser().name.toLowerCase()); | |||
} | |||
set_fullwidth_if_enabled() { | |||
frappe.ui.toolbar.set_fullwidth_if_enabled(); | |||
} | |||
set_rtl() { | |||
if (frappe.utils.is_rtl()) { | |||
$('body').addClass('frappe-rtl'); | |||
} | |||
} | |||
show_notes() { | |||
var me = this; | |||
if (frappe.boot.notes.length) { | |||
frappe.boot.notes.forEach(function (note) { | |||
if (!note.seen || note.notify_on_every_login) { | |||
var d = frappe.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) { | |||
frappe.call({ | |||
method: "frappe.desk.doctype.note.note.mark_as_seen", | |||
args: { | |||
note: note.name, | |||
}, | |||
}); | |||
} | |||
// next note | |||
me.show_notes(); | |||
}; | |||
} | |||
}); | |||
} | |||
} | |||
setup_build_events() { | |||
if (frappe.boot.developer_mode) { | |||
frappe.require("build_events.bundle.js"); | |||
} | |||
} | |||
setup_energy_point_listeners() { | |||
frappe.realtime.on("energy_point_alert", (message) => { | |||
frappe.show_alert(message); | |||
}); | |||
} | |||
setup_copy_doc_listener() { | |||
$("body").on("paste", (e) => { | |||
try { | |||
let pasted_data = frappe.utils.get_clipboard_data(e); | |||
let doc = JSON.parse(pasted_data); | |||
if (doc.doctype) { | |||
e.preventDefault(); | |||
const sleep = frappe.utils.sleep; | |||
frappe.dom.freeze(__("Creating {0}", [doc.doctype]) + "..."); | |||
// to avoid abrupt UX | |||
// wait for activity feedback | |||
sleep(500).then(() => { | |||
let res = frappe.model.with_doctype(doc.doctype, () => { | |||
let newdoc = frappe.model.copy_doc(doc); | |||
newdoc.__newname = doc.name; | |||
delete doc.name; | |||
newdoc.idx = null; | |||
newdoc.__run_link_triggers = false; | |||
frappe.set_route("Form", newdoc.doctype, newdoc.name); | |||
frappe.dom.unfreeze(); | |||
}); | |||
res && res.fail(frappe.dom.unfreeze); | |||
}); | |||
} | |||
} catch (e) { | |||
// | |||
} | |||
}); | |||
} | |||
setup_moment() { | |||
moment.updateLocale("en", { | |||
week: { | |||
dow: frappe.datetime.get_first_day_of_the_week_index(), | |||
}, | |||
}); | |||
moment.locale("en"); | |||
moment.user_utc_offset = moment().utcOffset(); | |||
if (frappe.boot.timezone_info) { | |||
moment.tz.add(frappe.boot.timezone_info); | |||
} | |||
} | |||
}; | |||
frappe.get_module = function (m, default_module) { | |||
var module = frappe.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; | |||
}; | |||
@@ -1,102 +0,0 @@ | |||
import Picker from "../icon_picker/icon_picker"; | |||
import dv_icons_list from "../icon_picker/icons_list"; | |||
frappe.ui.form.ControlIcon = class ControlIcon extends frappe.ui.form.ControlData { | |||
make_input() { | |||
this.df.placeholder = this.df.placeholder || __("Choose an icon"); | |||
super.make_input(); | |||
this.make_icon_input(); | |||
} | |||
get_all_icons() { | |||
frappe.symbols = []; | |||
$("#frappe-symbols > symbol[id]").each(function () { | |||
this.id.includes("icon-") && frappe.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'; | |||
} | |||
}; |
@@ -1,89 +0,0 @@ | |||
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">${frappe.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; |
@@ -1,795 +0,0 @@ | |||
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; |
@@ -1,443 +0,0 @@ | |||
frappe.provide('frappe.search'); | |||
frappe.ui.Notifications = class Notifications { | |||
constructor() { | |||
this.tabs = {}; | |||
this.notification_settings = frappe.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 = frappe.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"> | |||
${frappe.utils.icon('setting-gear')} | |||
</span>`) | |||
.on('click', (e) => { | |||
e.stopImmediatePropagation(); | |||
this.dropdown.dropdown('hide'); | |||
frappe.set_route('Form', 'Notification Settings', frappe.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"> | |||
${frappe.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'); | |||
frappe.call( | |||
'frappe.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); | |||
}); | |||
} | |||
}; | |||
frappe.ui.notifications = { | |||
get_notification_config() { | |||
return frappe.xcall('frappe.desk.notifications.get_notification_info').then(r => { | |||
frappe.ui.notifications.config = r; | |||
return r; | |||
}); | |||
}, | |||
show_open_count_list(doctype) { | |||
if (!frappe.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 = frappe.ui.notifications.config['conditions'][doctype]; | |||
if (filters && $.isPlainObject(filters)) { | |||
if (!frappe.route_options) { | |||
frappe.route_options = {}; | |||
} | |||
$.extend(frappe.route_options, filters); | |||
} | |||
frappe.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) { | |||
frappe.call( | |||
'frappe.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], frappe.ellipsis(strip_html(title[1]), 100)) : message; | |||
let timestamp = frappe.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 = frappe.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/frappe/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 frappe.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 frappe.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) { | |||
frappe.call( | |||
'frappe.desk.doctype.notification_settings.notification_settings.set_seen_value', | |||
{ | |||
value: cint(flag), | |||
user: frappe.session.user | |||
} | |||
); | |||
} | |||
setup_notification_listeners() { | |||
frappe.realtime.on('notification', () => { | |||
this.toggle_notification_icon(false); | |||
this.update_dropdown(); | |||
}); | |||
frappe.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); | |||
frappe.call( | |||
'frappe.desk.doctype.notification_log.notification_log.trigger_indicator_hide' | |||
); | |||
} | |||
}); | |||
} | |||
} | |||
class EventsView extends BaseNotificationsView { | |||
make() { | |||
let today = frappe.datetime.get_today(); | |||
frappe.xcall('frappe.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 = frappe.datetime.get_time(event.starts_on); | |||
let days_diff = frappe.datetime.get_day_diff(event.ends_on, event.starts_on); | |||
let end_time = frappe.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 = frappe.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/frappe/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); | |||
} | |||
} |
@@ -1,84 +0,0 @@ | |||
<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> |
@@ -1,911 +0,0 @@ | |||
// Copyright (c) 2015, Frappe 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 {frappe.ui.Page} | |||
*/ | |||
/** | |||
* @typedef {Object} frappe.ui.Page | |||
*/ | |||
frappe.ui.make_app_page = function (opts) { | |||
opts.parent.page = new frappe.ui.Page(opts); | |||
return opts.parent.page; | |||
} | |||
frappe.ui.pages = {}; | |||
frappe.ui.Page = Class.extend({ | |||
init: function (opts) { | |||
$.extend(this, opts); | |||
this.set_document_title = true; | |||
this.buttons = {}; | |||
this.fields_dict = {}; | |||
this.views = {}; | |||
this.make(); | |||
frappe.ui.pages[frappe.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) { | |||
frappe.require(this.required_libs, callback); | |||
}, | |||
add_main_section: function () { | |||
$(frappe.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('frappe-card'); | |||
// keyboard shortcuts | |||
let menu_btn = this.menu_btn_group.find('button'); | |||
menu_btn.attr("title", __("Menu")).tooltip({delay: {"show": 600, "hide": 100}}); | |||
frappe.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'); | |||
frappe.ui.keys.get_shortcut_group(this.page_actions[0]).add(action_btn, action_btn.find('.actions-btn-group-label')); | |||
let route = frappe.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 (frappe.utils.is_xs() || frappe.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 (frappe.utils.is_xs() || frappe.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 (frappe.utils.is_xs() || frappe.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(frappe.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"> | |||
${frappe.utils.icon(icon)} | |||
</button> | |||
`); | |||
button.appendTo(this.icon_group.removeClass("hide")); | |||
button.click(click); | |||
button.attr("title", __(tooltip_label || frappe.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 ? frappe.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'); | |||
frappe.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">${frappe.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> | |||
`); | |||
frappe.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 | |||
frappe.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 (frappe.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} | |||
${frappe.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; | |||
frappe.utils.set_title(tab_title || title); | |||
if (icon) { | |||
title = `${frappe.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 ? frappe.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> | |||
${frappe.utils.icon('select', 'xs')} | |||
</span>`; | |||
if (icon) { | |||
dropdown_label = `<span class="hidden-xs"> | |||
${frappe.utils.icon(icon)} | |||
<span class="custom-btn-group-label">${__(label)}</span> | |||
${frappe.utils.icon('select', 'xs')} | |||
</span> | |||
<span class="visible-xs"> | |||
${frappe.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) { | |||
frappe.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 = frappe.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'); | |||
}, | |||
}); |
@@ -1,145 +0,0 @@ | |||
<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 frappe.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> |
@@ -1,52 +0,0 @@ | |||
// 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 frappe.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 | |||
} | |||
frappe.db.set_value('Theme Settings', 'Theme Settings', { | |||
'dark_view': data.dark_style, | |||
'theme_color': data.color_name | |||
}, function () { | |||
frappe.ui.toolbar.clear_cache(); | |||
setTimeout(() => d.hide(), 1000); | |||
}); | |||
} | |||
}); | |||
d.show(); | |||
}); |
@@ -1,293 +0,0 @@ | |||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt | |||
frappe.provide("frappe.ui.toolbar"); | |||
frappe.provide("frappe.search"); | |||
frappe.ui.toolbar.Toolbar = class { | |||
constructor() { | |||
$("header").replaceWith( | |||
frappe.render_template("navbar", { | |||
avatar: frappe.avatar(frappe.session.user, "avatar-medium"), | |||
navbar_settings: frappe.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(() => { | |||
frappe.ui.toolbar.toggle_full_width(); | |||
}); | |||
} | |||
setup_help() { | |||
if (!frappe.boot.desk_settings.notifications) { | |||
// hide the help section | |||
$(".navbar .vertical-bar").removeClass("d-sm-block"); | |||
$(".dropdown-help").removeClass("d-lg-block"); | |||
return; | |||
} | |||
frappe.provide("frappe.help"); | |||
frappe.help.show_results = show_results; | |||
this.search = new frappe.search.SearchDialog(); | |||
frappe.provide("frappe.searchdialog"); | |||
frappe.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 = frappe.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 = frappe.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 = frappe.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 (frappe.boot.desk_settings.search_bar) { | |||
let awesome_bar = new frappe.search.AwesomeBar(); | |||
awesome_bar.setup("#navbar-search"); | |||
// TODO: Remove this in v14 | |||
frappe.search.utils.make_function_searchable(function () { | |||
frappe.set_route("List", "Client Script"); | |||
}, __("Custom Script List")); | |||
} | |||
} | |||
setup_notifications() { | |||
if (frappe.boot.desk_settings.notifications && frappe.session.user !== "Guest") { | |||
this.notifications = new frappe.ui.Notifications(); | |||
} | |||
} | |||
}; | |||
$.extend(frappe.ui.toolbar, { | |||
add_dropdown_button: function (parent, label, click, icon) { | |||
var menu = frappe.ui.toolbar.get_menu(parent); | |||
if (menu.find("li:not(.custom-menu)").length && !menu.find(".divider").length) { | |||
frappe.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" ? frappe.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="${frappe.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; | |||
frappe.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(); | |||
frappe.ui.keys.show_keyboard_shortcut_dialog(); | |||
return false; | |||
}, | |||
}); | |||
frappe.ui.toolbar.clear_cache = frappe.utils.throttle(function () { | |||
frappe.assets.clear_local_storage(); | |||
frappe.xcall("frappe.sessions.clear").then((message) => { | |||
frappe.show_alert({ | |||
message: message, | |||
indicator: "info", | |||
}); | |||
location.reload(true); | |||
}); | |||
}, 10000); | |||
frappe.ui.toolbar.show_about = function () { | |||
try { | |||
frappe.ui.misc.about(); | |||
} catch (e) { | |||
console.log(e); | |||
} | |||
return false; | |||
}; | |||
frappe.ui.toolbar.route_to_user = function () { | |||
frappe.set_route("Form", "User", frappe.session.user); | |||
}; | |||
frappe.ui.toolbar.view_website = function () { | |||
let website_tab = window.open(); | |||
website_tab.opener = null; | |||
website_tab.location = "/index"; | |||
}; | |||
frappe.ui.toolbar.setup_session_defaults = function () { | |||
let fields = []; | |||
frappe.call({ | |||
method: "frappe.core.doctype.session_default_settings.session_default_settings.get_session_default_values", | |||
callback: function (data) { | |||
fields = JSON.parse(data.message); | |||
let perms = frappe.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(frappe.user_roles, "System Manager") || perms[0].read == 1) { | |||
fields[fields.length] = { | |||
fieldname: "settings", | |||
fieldtype: "Button", | |||
label: __("Settings"), | |||
click: () => { | |||
frappe.set_route( | |||
"Form", | |||
"Session Default Settings", | |||
"Session Default Settings" | |||
); | |||
}, | |||
}; | |||
} | |||
frappe.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] = ""; | |||
} | |||
}); | |||
frappe.call({ | |||
method: "frappe.core.doctype.session_default_settings.session_default_settings.set_session_default_values", | |||
args: { | |||
default_values: values, | |||
}, | |||
callback: function (data) { | |||
if (data.message == "success") { | |||
frappe.show_alert({ | |||
message: __("Session Defaults Saved"), | |||
indicator: "green", | |||
}); | |||
frappe.ui.toolbar.clear_cache(); | |||
} else { | |||
frappe.show_alert({ | |||
message: __( | |||
"An error occurred while setting Session Defaults" | |||
), | |||
indicator: "red", | |||
}); | |||
} | |||
}, | |||
}); | |||
}, | |||
__("Session Defaults"), | |||
__("Save") | |||
); | |||
}, | |||
}); | |||
}; |
@@ -1,202 +0,0 @@ | |||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt | |||
frappe.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 = frappe.breadcrumbs.current_page(); | |||
breadcrumb = breadcrumb.split('/'); | |||
this.all[frappe.breadcrumbs.current_page()] = obj; | |||
this.update(); | |||
}, | |||
current_page() { | |||
return frappe.get_route_str(); | |||
}, | |||
update() { | |||
var breadcrumbs = this.all[frappe.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 = frappe.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 && frappe.visible_modules.includes(breadcrumbs.module_info.module)) { | |||
$(`<li><a href="/app/${frappe.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 = frappe.get_module(breadcrumbs.module); | |||
// set workspace | |||
if (breadcrumbs.module_info && frappe.boot.module_page_map[breadcrumbs.module]) { | |||
breadcrumbs.workspace = frappe.boot.module_page_map[breadcrumbs.module]; | |||
} | |||
} | |||
}, | |||
set_list_breadcrumb(breadcrumbs) { | |||
const doctype = breadcrumbs.doctype; | |||
const doctype_meta = frappe.get_doc('DocType', doctype); | |||
if ((doctype === "User" && !frappe.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 = frappe.router.slug(frappe.router.doctype_layout || doctype); | |||
if (frappe.boot.treeviews.indexOf(doctype) !== -1) { | |||
let view = frappe.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 = frappe.get_route()[2]; | |||
let form_route = `/app/${frappe.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(); | |||
frappe.utils.copy_to_clipboard(last_crumb.text()); | |||
}); | |||
} | |||
}, | |||
setup_modules() { | |||
if (!frappe.visible_modules) { | |||
frappe.visible_modules = $.map(frappe.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 frappe.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; | |||
} | |||
} | |||
} |
@@ -1,129 +0,0 @@ | |||
// Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
// MIT License. See license.txt | |||
// page container | |||
frappe.provide("frappe.pages"); | |||
frappe.provide("frappe.views"); | |||
window.cur_page = null; | |||
frappe.modules_list = []; | |||
frappe.module_items_list = []; | |||
frappe.active_module = {}; | |||
frappe.theme_settings = {}; | |||
frappe.is_app_loaded = false; | |||
frappe.is_page_changed = false; | |||
frappe.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'); | |||
frappe.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 = frappe.get_route_str(); | |||
var route_obj = frappe.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) { | |||
frappe.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; | |||
frappe.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 = frappe.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 = frappe.router.get_sub_path(); | |||
$(this.page).trigger("show"); | |||
!this.page.disable_scroll_to_top && frappe.utils.scroll_to(0); | |||
frappe.breadcrumbs.update(); | |||
return this.page; | |||
} | |||
has_sidebar() { | |||
var flag = 0; | |||
var route_str = frappe.get_route_str(); | |||
// check in frappe.ui.pages | |||
flag = frappe.ui.pages[route_str] && !frappe.ui.pages[route_str].single_column; | |||
// sometimes frappe.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; | |||
} | |||
}; |
@@ -22,7 +22,7 @@ | |||
</div> | |||
<ul class="list-unstyled mobile-modules-menu-list" v-if="is_shown_mobile_menu && module_items_list[active_module.name] && module_items_list[active_module.name].length"> | |||
<li :class="(active_module.name==current_doctype)?'active':''"> | |||
<a v-on:click="open_dashboard(active_module.name)" :data-dashboard="active_module.name">{{ frappe._("Dashboard") }}</a> | |||
<a v-on:click="open_dashboard(active_module.name)" :data-dashboard="active_module.name">{{ xhiveframework._("Dashboard") }}</a> | |||
</li> | |||
<li v-for="item in module_items_list[active_module.name]"> | |||
<a> {{ item.label }} <i class="far fa-angle-down sub-menu-arrow"></i></a> | |||
@@ -53,7 +53,7 @@ | |||
<div><i :class="get_module_icon(module.name,module.icon)+' animated-icon'"></i></div> | |||
<span v-if="theme_settings.show_icon_label && theme_settings.show_icon_label=='1'">{{ (module.label) ? module.label : module.name }}</span> | |||
<!-- <i :class="get_module_icon(module.name,module.icon)+' animated-icon'"></i>--> | |||
<!-- <span v-html="frappe.utils.icon(module.icon || 'folder-normal', 'lg')"></span>--> | |||
<!-- <span v-html="xhiveframework.utils.icon(module.icon || 'folder-normal', 'lg')"></span>--> | |||
</a> | |||
</li> | |||
</ul> | |||
@@ -84,8 +84,8 @@ export default { | |||
name: "Menu", | |||
data() { | |||
return { | |||
route: frappe.get_route(), | |||
is_rtl: frappe.utils.is_rtl(), | |||
route: xhiveframework.get_route(), | |||
is_rtl: xhiveframework.utils.is_rtl(), | |||
theme_settings: {}, | |||
current_doctype: '', | |||
current_page: '', | |||
@@ -121,8 +121,8 @@ export default { | |||
"Website": "flaticon-browser", | |||
"Settings": "fal fa-cog", | |||
"Utilities": 'flaticon-configuration', | |||
"ERPNext Settings": 'flaticon-admin', | |||
"ERPNext Integrations": 'flaticon-configuration', | |||
"XhiveERP Settings": 'flaticon-admin', | |||
"XhiveERP Integrations": 'flaticon-configuration', | |||
}, | |||
modules_list: [], | |||
module_items_list: {}, | |||
@@ -132,31 +132,31 @@ export default { | |||
methods: { | |||
get_modules: function (callback) { | |||
const $this = this; | |||
frappe.call({ | |||
xhiveframework.call({ | |||
type: 'POST', | |||
method: 'frappe.desk.desktop.get_workspace_sidebar_items', | |||
method: 'xhiveframework.desk.desktop.get_workspace_sidebar_items', | |||
args: {}, | |||
callback: callback | |||
}); | |||
}, | |||
get_module_items: function (module = '', callback) { | |||
const $this = this; | |||
frappe.call({ | |||
xhiveframework.call({ | |||
type: 'POST', | |||
method: 'frappe.desk.desktop.get_desktop_page', | |||
method: 'xhiveframework.desk.desktop.get_desktop_page', | |||
args: {page: '{"name":"' + module + '","title":"' + module + '"}'}, | |||
callback: callback | |||
}); | |||
}, | |||
get_module_name_from_doctype: function () { | |||
const $this = this; | |||
const route = frappe.get_route(); | |||
const route = xhiveframework.get_route(); | |||
$this.current_doctype = (route && route.length >= 2 && route[1]) ? route[1] : ''; | |||
if (route && route[0] && route[0] == 'dashboard-view') { | |||
$this.current_doctype = 'Dashboard'; | |||
} | |||
$this.is_dashboard = (route && route.length == 2 && route[1] && route[0] && route[0] == 'dashboard-view') ? true : false; | |||
frappe.call({ | |||
xhiveframework.call({ | |||
type: 'POST', | |||
method: 'datavalue_theme_14.api.get_module_name_from_doctype', | |||
args: { | |||
@@ -175,7 +175,7 @@ export default { | |||
}); | |||
}, | |||
module_menu_list: function (current_module) { | |||
const route = frappe.get_route(); | |||
const route = xhiveframework.get_route(); | |||
let _module = current_module; | |||
if (route && route[0] && route[0] == 'Workspaces') { | |||
_module = route[1]; | |||
@@ -248,7 +248,7 @@ export default { | |||
}, | |||
after_side_menu_items: function () { | |||
const $this = this; | |||
const route = frappe.get_route(); | |||
const route = xhiveframework.get_route(); | |||
$this.current_doctype = (route && route.length >= 2 && route[1]) ? route[1] : ''; | |||
setTimeout(() => { | |||
$('.side-menu .side-menu-items > ul.dropdown-list').niceScroll({ | |||
@@ -303,7 +303,7 @@ export default { | |||
if ($this.theme_settings && Object.keys($this.theme_settings).length) { | |||
callback(); | |||
} else { | |||
frappe.call({ | |||
xhiveframework.call({ | |||
type: 'POST', | |||
method: 'datavalue_theme_14.api.get_theme_settings', | |||
args: {}, | |||
@@ -323,7 +323,7 @@ export default { | |||
if (link.link_type == "Report" && !link.is_query_report) { | |||
opts.doctype = link.dependencies; | |||
} | |||
const route = frappe.utils.generate_route(opts); | |||
const route = xhiveframework.utils.generate_route(opts); | |||
return route; | |||
}, | |||
open_module: function (module, is_mobile = false) { | |||
@@ -332,9 +332,9 @@ export default { | |||
setTimeout(() => this.module_menu_list(module), 100); | |||
if (is_mobile == false) { | |||
if ($('body').data('menu-opening-type') == 'Dashboard') { | |||
frappe.set_route('/dashboard-view/' + (module)); | |||
xhiveframework.set_route('/dashboard-view/' + (module)); | |||
} else { | |||
frappe.set_route('/' + (module.replace(/ /g, "-")).toLowerCase()); | |||
xhiveframework.set_route('/' + (module.replace(/ /g, "-")).toLowerCase()); | |||
} | |||
$('.btn-toggle-main-menu').addClass('menu-shown'); | |||
$('body').removeClass('hide-main-menu'); | |||
@@ -343,7 +343,7 @@ export default { | |||
} | |||
}, | |||
open_dashboard: function (module) { | |||
frappe.set_route('/dashboard-view/' + (module)); | |||
xhiveframework.set_route('/dashboard-view/' + (module)); | |||
}, | |||
mobile_back_modules: function () { | |||
const $this = this; | |||
@@ -366,9 +366,9 @@ export default { | |||
} | |||
}, | |||
created() { | |||
const route = frappe.get_route(); | |||
const route = xhiveframework.get_route(); | |||
this.current_doctype = (route && route.length >= 2 && route[1]) ? route[1] : ''; | |||
if ($('body').hasClass('frappe-rtl')) { | |||
if ($('body').hasClass('xhiveframework-rtl')) { | |||
this.menu_items_animate = 'slideInRight'; | |||
} | |||
this.get_theme_settings(() => { | |||
@@ -5,7 +5,7 @@ | |||
if ($('#page-login').length) { | |||
$('#page-login').each(function () { | |||
let page = $(this); | |||
frappe.call({ | |||
xhiveframework.call({ | |||
type: 'POST', | |||
method: 'datavalue_theme_14.api.get_theme_settings', | |||
args: {}, | |||
@@ -1,6 +1,6 @@ | |||
@import 'partials/reset'; | |||
@import 'partials/grid'; | |||
@import 'partials/frappe'; | |||
@import 'partials/xhiveframework'; | |||
@import 'partials/tooltip'; | |||
@import 'partials/chosen'; | |||
@import 'partials/forms-ui'; | |||
@@ -1,6 +1,6 @@ | |||
@import 'partials/reset'; | |||
@import 'partials/grid'; | |||
@import 'partials/frappe'; | |||
@import 'partials/xhiveframework'; | |||
@import 'partials/tooltip'; | |||
@import 'partials/chosen'; | |||
@import 'partials/forms-ui'; | |||
@@ -7,7 +7,7 @@ body.hide-main-menu { | |||
margin-left: 80px; | |||
} | |||
&.frappe-rtl { | |||
&.xhiveframework-rtl { | |||
.dv-app-theme .dv-app-content { | |||
margin-left: 0 $imp; | |||
margin-right: 80px $imp; | |||
@@ -1,425 +0,0 @@ | |||
@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; | |||
} | |||
.frappe-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 .frappe-list .result, .layout-main-section .frappe-list .no-result, .layout-main-section .frappe-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; | |||
} | |||
.frappe-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; | |||
} | |||
} |
@@ -1,4 +1,4 @@ | |||
body.frappe-rtl { | |||
body.xhiveframework-rtl { | |||
direction: rtl; | |||
text-align: right; | |||
overflow-x: hidden $imp; | |||
@@ -180,7 +180,7 @@ body.frappe-rtl { | |||
text-align: right; | |||
} | |||
.frappe-control[data-fieldtype="Select"] .control-input .select-icon, .frappe-control[data-fieldtype="Select"].form-group .select-icon { | |||
.xhiveframework-control[data-fieldtype="Select"] .control-input .select-icon, .xhiveframework-control[data-fieldtype="Select"].form-group .select-icon { | |||
top: 6px; | |||
right: inherit; | |||
left: 12px; | |||
@@ -211,7 +211,7 @@ body.frappe-rtl { | |||
line-height: 21px; | |||
} | |||
.frappe-control[data-fieldtype="Select"] .control-input .placeholder, .frappe-control[data-fieldtype="Select"].form-group .placeholder { | |||
.xhiveframework-control[data-fieldtype="Select"] .control-input .placeholder, .xhiveframework-control[data-fieldtype="Select"].form-group .placeholder { | |||
right: 12px; | |||
left: inherit; | |||
} | |||
@@ -287,7 +287,7 @@ body.frappe-rtl { | |||
text-align: right; | |||
} | |||
.frappe-control { | |||
.xhiveframework-control { | |||
text-align: right; | |||
} | |||
@@ -530,7 +530,7 @@ body.frappe-rtl { | |||
margin-right: 0; | |||
} | |||
.frappe-control[data-fieldtype="Select"] .control-input select, .frappe-control[data-fieldtype="Select"].form-group select { | |||
.xhiveframework-control[data-fieldtype="Select"] .control-input select, .xhiveframework-control[data-fieldtype="Select"].form-group select { | |||
text-align: right $imp; | |||
} | |||
@@ -563,7 +563,7 @@ body.frappe-rtl { | |||
padding-right: 0px; | |||
padding-left: 15px; | |||
} | |||
.layout-main-section.form-dashboard-section, .layout-main-section.form-section.card-section, .layout-main-section.frappe-card { | |||
.layout-main-section.form-dashboard-section, .layout-main-section.form-section.card-section, .layout-main-section.xhiveframework-card { | |||
overflow: visible; | |||
} | |||
} | |||
@@ -17,11 +17,11 @@ login.bind_events = function () { | |||
event.preventDefault(); | |||
var args = {}; | |||
args.cmd = "login"; | |||
args.usr = frappe.utils.xss_sanitise(($("#login_email").val() || "").trim()); | |||
args.usr = xhiveframework.utils.xss_sanitise(($("#login_email").val() || "").trim()); | |||
args.pwd = $("#login_password").val(); | |||
args.device = "desktop"; | |||
if (!args.usr || !args.pwd) { | |||
frappe.msgprint('{{ _("Both login and password required") }}'); | |||
xhiveframework.msgprint('{{ _("Both login and password required") }}'); | |||
return false; | |||
} | |||
login.call(args); | |||
@@ -31,10 +31,10 @@ login.bind_events = function () { | |||
$(".form-signup").on("submit", function (event) { | |||
event.preventDefault(); | |||
var args = {}; | |||
args.cmd = "frappe.core.doctype.user.user.sign_up"; | |||
args.cmd = "xhiveframework.core.doctype.user.user.sign_up"; | |||
args.email = ($("#signup_email").val() || "").trim(); | |||
args.redirect_to = frappe.utils.sanitise_redirect(frappe.utils.get_url_arg("redirect-to")); | |||
args.full_name = frappe.utils.xss_sanitise(($("#signup_fullname").val() || "").trim()); | |||
args.redirect_to = xhiveframework.utils.sanitise_redirect(xhiveframework.utils.get_url_arg("redirect-to")); | |||
args.full_name = xhiveframework.utils.xss_sanitise(($("#signup_fullname").val() || "").trim()); | |||
if (!args.email || !validate_email(args.email) || !args.full_name) { | |||
login.set_status('{{ _("Valid email and name required") }}', 'red'); | |||
return false; | |||
@@ -46,7 +46,7 @@ login.bind_events = function () { | |||
$(".form-forgot").on("submit", function (event) { | |||
event.preventDefault(); | |||
var args = {}; | |||
args.cmd = "frappe.core.doctype.user.user.reset_password"; | |||
args.cmd = "xhiveframework.core.doctype.user.user.reset_password"; | |||
args.user = ($("#forgot_email").val() || "").trim(); | |||
if (!args.user) { | |||
login.set_status('{{ _("Valid Login id required.") }}', 'red'); | |||
@@ -138,7 +138,7 @@ login.signup = function () { | |||
login.call = function (args, callback) { | |||
login.set_status('{{ _("Verifying...") }}', 'blue'); | |||
return frappe.call({ | |||
return xhiveframework.call({ | |||
type: "POST", | |||
args: args, | |||
callback: callback, | |||
@@ -196,20 +196,20 @@ login.login_handlers = (function () { | |||
if (data.message == 'Logged In') { | |||
login.set_status('{{ _("Success") }}', 'green'); | |||
document.body.innerHTML = `{% include "templates/includes/splash_screen.html" %}`; | |||
window.location.href = frappe.utils.sanitise_redirect(frappe.utils.get_url_arg("redirect-to")) || data.home_page; | |||
window.location.href = xhiveframework.utils.sanitise_redirect(xhiveframework.utils.get_url_arg("redirect-to")) || data.home_page; | |||
} else if (data.message == 'Password Reset') { | |||
window.location.href = frappe.utils.sanitise_redirect(data.redirect_to); | |||
window.location.href = xhiveframework.utils.sanitise_redirect(data.redirect_to); | |||
} else if (data.message == "No App") { | |||
login.set_status("{{ _('Success') }}", 'green'); | |||
if (localStorage) { | |||
var last_visited = | |||
localStorage.getItem("last_visited") | |||
|| frappe.utils.sanitise_redirect(frappe.utils.get_url_arg("redirect-to")); | |||
|| xhiveframework.utils.sanitise_redirect(xhiveframework.utils.get_url_arg("redirect-to")); | |||
localStorage.removeItem("last_visited"); | |||
} | |||
if (data.redirect_to) { | |||
window.location.href = frappe.utils.sanitise_redirect(data.redirect_to); | |||
window.location.href = xhiveframework.utils.sanitise_redirect(data.redirect_to); | |||
} | |||
if (last_visited && last_visited != "/login") { | |||
@@ -234,7 +234,7 @@ login.login_handlers = (function () { | |||
login.set_status(data.message[1], 'red'); | |||
} else { | |||
login.set_status('{{ _("Success") }}', 'green'); | |||
frappe.msgprint(data.message[1]) | |||
xhiveframework.msgprint(data.message[1]) | |||
} | |||
//login.set_status(__(data.message), 'green'); | |||
} | |||
@@ -261,7 +261,7 @@ login.login_handlers = (function () { | |||
return login_handlers; | |||
})(); | |||
frappe.ready(function () { | |||
xhiveframework.ready(function () { | |||
login.bind_events(); | |||
@@ -281,9 +281,9 @@ var verify_token = function (event) { | |||
var args = {}; | |||
args.cmd = "login"; | |||
args.otp = $("#login_token").val(); | |||
args.tmp_id = frappe.get_cookie('tmp_id'); | |||
args.tmp_id = xhiveframework.get_cookie('tmp_id'); | |||
if (!args.otp) { | |||
frappe.msgprint('{{ _("Login token required") }}'); | |||
xhiveframework.msgprint('{{ _("Login token required") }}'); | |||
return false; | |||
} | |||
login.call(args); | |||
@@ -44,7 +44,7 @@ | |||
<div class="dv-content-overlay"></div> | |||
<div class="dv-app-content" id="body"></div> | |||
<footer></footer> | |||
{{ frappe.render_template('templates/side-menu.html', {}) }} | |||
{{ xhiveframework.render_template('templates/side-menu.html', {}) }} | |||
</div> | |||
<script type="text/javascript"> | |||
@@ -53,11 +53,11 @@ | |||
window.app = true; | |||
window.dev_server = {{ dev_server }}; | |||
if (!window.frappe) window.frappe = {}; | |||
if (!window.xhiveframework) window.xhiveframework = {}; | |||
frappe.boot = JSON.parse({{ boot }}); | |||
frappe._messages = frappe.boot["__messages"]; | |||
frappe.csrf_token = "{{ csrf_token }}"; | |||
xhiveframework.boot = JSON.parse({{ boot }}); | |||
xhiveframework._messages = xhiveframework.boot["__messages"]; | |||
xhiveframework.csrf_token = "{{ csrf_token }}"; | |||
</script> | |||
{% for include in include_js %} | |||
@@ -1,4 +1,4 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||
# License: MIT. See LICENSE | |||
no_cache = 1 | |||
@@ -7,42 +7,42 @@ import os | |||
import re | |||
import secrets | |||
import frappe | |||
import frappe.sessions | |||
from frappe import _ | |||
from frappe.utils.jinja_globals import is_rtl | |||
import xhiveframework | |||
import xhiveframework.sessions | |||
from xhiveframework import _ | |||
from xhiveframework.utils.jinja_globals import is_rtl | |||
SCRIPT_TAG_PATTERN = re.compile(r"\<script[^<]*\</script\>") | |||
CLOSING_SCRIPT_TAG_PATTERN = re.compile(r"</script\>") | |||
def get_context(context): | |||
if frappe.session.user == "Guest": | |||
frappe.throw(_("Log in to access this page."), frappe.PermissionError) | |||
if xhiveframework.session.user == "Guest": | |||
xhiveframework.throw(_("Log in to access this page."), xhiveframework.PermissionError) | |||
elif ( | |||
frappe.db.get_value("User", frappe.session.user, "user_type", order_by=None) == "Website User" | |||
xhiveframework.db.get_value("User", xhiveframework.session.user, "user_type", order_by=None) == "Website User" | |||
): | |||
frappe.throw(_("You are not permitted to access this page."), frappe.PermissionError) | |||
xhiveframework.throw(_("You are not permitted to access this page."), xhiveframework.PermissionError) | |||
hooks = frappe.get_hooks() | |||
hooks = xhiveframework.get_hooks() | |||
try: | |||
boot = frappe.sessions.get() | |||
boot = xhiveframework.sessions.get() | |||
except Exception as e: | |||
boot = frappe._dict(status="failed", error=str(e)) | |||
print(frappe.get_traceback()) | |||
boot = xhiveframework._dict(status="failed", error=str(e)) | |||
print(xhiveframework.get_traceback()) | |||
# this needs commit | |||
csrf_token = frappe.sessions.get_csrf_token() | |||
csrf_token = xhiveframework.sessions.get_csrf_token() | |||
frappe.db.commit() | |||
xhiveframework.db.commit() | |||
theme_settings_list = {} | |||
theme_settings = frappe.db.sql(""" SELECT * FROM tabSingles WHERE doctype = 'Theme Settings'; """, as_dict=True) | |||
theme_settings = xhiveframework.db.sql(""" SELECT * FROM tabSingles WHERE doctype = 'Theme Settings'; """, as_dict=True) | |||
for theme_setting in theme_settings: | |||
theme_settings_list[theme_setting['field']] = theme_setting['value'] | |||
boot_json = frappe.as_json(boot, indent=None, separators=(",", ":")) | |||
boot_json = xhiveframework.as_json(boot, indent=None, separators=(",", ":")) | |||
# remove script tags from boot | |||
boot_json = SCRIPT_TAG_PATTERN.sub("", boot_json) | |||
@@ -57,19 +57,19 @@ def get_context(context): | |||
context.update( | |||
{ | |||
"no_cache": 1, | |||
"build_version": frappe.utils.get_build_version(), | |||
"build_version": xhiveframework.utils.get_build_version(), | |||
"build_version_dev": secrets.randbits(50), | |||
"include_js": hooks["app_include_js"], | |||
"include_css": hooks["app_include_css"], | |||
"layout_direction": "rtl" if is_rtl() else "ltr", | |||
"lang": frappe.local.lang, | |||
"lang": xhiveframework.local.lang, | |||
"sounds": hooks["sounds"], | |||
"boot": boot if context.get("for_mobile") else boot_json, | |||
"desk_theme": boot.get("desk_theme") or "Light", | |||
"csrf_token": csrf_token, | |||
"google_analytics_id": frappe.conf.get("google_analytics_id"), | |||
"google_analytics_anonymize_ip": frappe.conf.get("google_analytics_anonymize_ip"), | |||
"mixpanel_id": frappe.conf.get("mixpanel_id"), | |||
"google_analytics_id": xhiveframework.conf.get("google_analytics_id"), | |||
"google_analytics_anonymize_ip": xhiveframework.conf.get("google_analytics_anonymize_ip"), | |||
"mixpanel_id": xhiveframework.conf.get("mixpanel_id"), | |||
"get_theme_settings": theme_settings_list, | |||
"dark_theme": theme | |||
} | |||
@@ -78,7 +78,7 @@ def get_context(context): | |||
return context | |||
@frappe.whitelist() | |||
@xhiveframework.whitelist() | |||
def get_desk_assets(build_version): | |||
"""Get desk assets to be loaded for mobile app""" | |||
data = get_context({"for_mobile": True}) | |||
@@ -92,8 +92,8 @@ def get_desk_assets(build_version): | |||
if path.startswith("/assets/"): | |||
path = path.replace("/assets/", "assets/") | |||
try: | |||
with open(os.path.join(frappe.local.sites_path, path)) as f: | |||
assets[0]["data"] = assets[0]["data"] + "\n" + frappe.safe_decode(f.read(), "utf-8") | |||
with open(os.path.join(xhiveframework.local.sites_path, path)) as f: | |||
assets[0]["data"] = assets[0]["data"] + "\n" + xhiveframework.safe_decode(f.read(), "utf-8") | |||
except OSError: | |||
pass | |||
@@ -101,8 +101,8 @@ def get_desk_assets(build_version): | |||
if path.startswith("/assets/"): | |||
path = path.replace("/assets/", "assets/") | |||
try: | |||
with open(os.path.join(frappe.local.sites_path, path)) as f: | |||
assets[1]["data"] = assets[1]["data"] + "\n" + frappe.safe_decode(f.read(), "utf-8") | |||
with open(os.path.join(xhiveframework.local.sites_path, path)) as f: | |||
assets[1]["data"] = assets[1]["data"] + "\n" + xhiveframework.safe_decode(f.read(), "utf-8") | |||
except OSError: | |||
pass | |||
@@ -73,7 +73,7 @@ | |||
<div class="login-content page-card"> | |||
<div class="login-content-bg"> | |||
<img class="app-logo" src="{{ logo }}"> | |||
<img class="app-login-bg" src="/assets/datavalue_theme_14/images/erpnext-hero-compressed.png"> | |||
<img class="app-login-bg" src="/assets/datavalue_theme_14/images/xhiveerp-hero-compressed.png"> | |||
<div class="text-center login-copyrights">Powered By <a href="https://www.datavaluenet.net/" target="_blank">Data Value</a></div> | |||
</div> | |||
<div class="login-content-form"> | |||
@@ -134,7 +134,7 @@ | |||
<div class="login-content page-card"> | |||
<div class="login-content-bg"> | |||
<img class="app-logo" src="{{ logo }}"> | |||
<img class="app-login-bg" src="/assets/datavalue_theme_14/images/erpnext-hero-compressed.png"> | |||
<img class="app-login-bg" src="/assets/datavalue_theme_14/images/xhiveerp-hero-compressed.png"> | |||
<div class="text-center login-copyrights">Powered By <a href="https://www.datavaluenet.net/" target="_blank">Data Value</a></div> | |||
</div> | |||
<div class="login-content-form"> | |||
@@ -187,7 +187,7 @@ | |||
<div class="login-content page-card"> | |||
<div class="login-content-bg"> | |||
<img class="app-logo" src="{{ logo }}"> | |||
<img class="app-login-bg" src="/assets/datavalue_theme_14/images/erpnext-hero-compressed.png"> | |||
<img class="app-login-bg" src="/assets/datavalue_theme_14/images/xhiveerp-hero-compressed.png"> | |||
<div class="text-center login-copyrights">Powered By <a href="https://www.datavaluenet.net/" target="_blank">Data Value</a></div> | |||
</div> | |||
<div class="login-content-form"> | |||
@@ -1,54 +1,54 @@ | |||
# Copyright (c) 2015, Frappe Technologies Pvt. Ltd. and Contributors | |||
# Copyright (c) 2015, Xhiveframework Technologies Pvt. Ltd. and Contributors | |||
# MIT License. See license.txt | |||
from __future__ import unicode_literals | |||
import secrets | |||
import frappe | |||
import frappe.utils | |||
from frappe.utils.oauth import get_oauth2_authorize_url, get_oauth_keys, login_via_oauth2, login_via_oauth2_id_token, login_oauth_user as _login_oauth_user, redirect_post_login | |||
import xhiveframework | |||
import xhiveframework.utils | |||
from xhiveframework.utils.oauth import get_oauth2_authorize_url, get_oauth_keys, login_via_oauth2, login_via_oauth2_id_token, login_oauth_user as _login_oauth_user, redirect_post_login | |||
import json | |||
from frappe import _ | |||
from frappe.auth import LoginManager | |||
from frappe.integrations.doctype.ldap_settings.ldap_settings import LDAPSettings | |||
from frappe.utils.password import get_decrypted_password | |||
from frappe.utils.html_utils import get_icon_html | |||
from frappe.integrations.oauth2_logins import decoder_compat | |||
from frappe.website.utils import get_home_page | |||
from xhiveframework import _ | |||
from xhiveframework.auth import LoginManager | |||
from xhiveframework.integrations.doctype.ldap_settings.ldap_settings import LDAPSettings | |||
from xhiveframework.utils.password import get_decrypted_password | |||
from xhiveframework.utils.html_utils import get_icon_html | |||
from xhiveframework.integrations.oauth2_logins import decoder_compat | |||
from xhiveframework.website.utils import get_home_page | |||
no_cache = True | |||
def get_context(context): | |||
redirect_to = frappe.local.request.args.get("redirect-to") | |||
redirect_to = xhiveframework.local.request.args.get("redirect-to") | |||
if frappe.session.user != "Guest": | |||
if xhiveframework.session.user != "Guest": | |||
if not redirect_to: | |||
if frappe.session.data.user_type=="Website User": | |||
if xhiveframework.session.data.user_type=="Website User": | |||
redirect_to = get_home_page() | |||
else: | |||
redirect_to = "/app" | |||
if redirect_to != 'login': | |||
frappe.local.flags.redirect_location = redirect_to | |||
raise frappe.Redirect | |||
xhiveframework.local.flags.redirect_location = redirect_to | |||
raise xhiveframework.Redirect | |||
# get settings from site config | |||
context.no_header = True | |||
context.for_test = 'login.html' | |||
context["title"] = "Login" | |||
context["provider_logins"] = [] | |||
context["disable_signup"] = frappe.utils.cint(frappe.db.get_single_value("Website Settings", "disable_signup")) | |||
context["logo"] = (frappe.db.get_single_value('Website Settings', 'app_logo') or | |||
frappe.get_hooks("app_logo_url")[-1]) | |||
context["app_name"] = (frappe.db.get_single_value('Website Settings', 'app_name') or | |||
frappe.get_system_settings("app_name") or _("Frappe")) | |||
providers = [i.name for i in frappe.get_all("Social Login Key", filters={"enable_social_login":1}, order_by="name")] | |||
context["disable_signup"] = xhiveframework.utils.cint(xhiveframework.db.get_single_value("Website Settings", "disable_signup")) | |||
context["logo"] = (xhiveframework.db.get_single_value('Website Settings', 'app_logo') or | |||
xhiveframework.get_hooks("app_logo_url")[-1]) | |||
context["app_name"] = (xhiveframework.db.get_single_value('Website Settings', 'app_name') or | |||
xhiveframework.get_system_settings("app_name") or _("Xhiveframework")) | |||
providers = [i.name for i in xhiveframework.get_all("Social Login Key", filters={"enable_social_login":1}, order_by="name")] | |||
for provider in providers: | |||
client_id, base_url = frappe.get_value("Social Login Key", provider, ["client_id", "base_url"]) | |||
client_id, base_url = xhiveframework.get_value("Social Login Key", provider, ["client_id", "base_url"]) | |||
client_secret = get_decrypted_password("Social Login Key", provider, "client_secret") | |||
provider_name = frappe.get_value("Social Login Key", provider, "provider_name") | |||
provider_name = xhiveframework.get_value("Social Login Key", provider, "provider_name") | |||
icon = None | |||
icon_url = frappe.get_value("Social Login Key", provider, "icon") | |||
icon_url = xhiveframework.get_value("Social Login Key", provider, "icon") | |||
if icon_url: | |||
if provider_name != "Custom": | |||
icon = "<img src='{0}' alt={1}>".format(icon_url, provider_name) | |||
@@ -68,10 +68,10 @@ def get_context(context): | |||
login_label = [_("Email")] | |||
if frappe.utils.cint(frappe.get_system_settings("allow_login_using_mobile_number")): | |||
if xhiveframework.utils.cint(xhiveframework.get_system_settings("allow_login_using_mobile_number")): | |||
login_label.append(_("Mobile")) | |||
if frappe.utils.cint(frappe.get_system_settings("allow_login_using_user_name")): | |||
if xhiveframework.utils.cint(xhiveframework.get_system_settings("allow_login_using_user_name")): | |||
login_label.append(_("Username")) | |||
context['login_label'] = ' {0} '.format(_('or')).join(login_label) | |||
@@ -79,34 +79,34 @@ def get_context(context): | |||
return context | |||
@frappe.whitelist(allow_guest=True) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def login_via_google(code, state): | |||
login_via_oauth2("google", code, state, decoder=decoder_compat) | |||
@frappe.whitelist(allow_guest=True) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def login_via_github(code, state): | |||
login_via_oauth2("github", code, state) | |||
@frappe.whitelist(allow_guest=True) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def login_via_facebook(code, state): | |||
login_via_oauth2("facebook", code, state, decoder=decoder_compat) | |||
@frappe.whitelist(allow_guest=True) | |||
def login_via_frappe(code, state): | |||
login_via_oauth2("frappe", code, state, decoder=decoder_compat) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def login_via_xhiveframework(code, state): | |||
login_via_oauth2("xhiveframework", code, state, decoder=decoder_compat) | |||
@frappe.whitelist(allow_guest=True) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def login_via_office365(code, state): | |||
login_via_oauth2_id_token("office_365", code, state, decoder=decoder_compat) | |||
@frappe.whitelist(allow_guest=True) | |||
@xhiveframework.whitelist(allow_guest=True) | |||
def login_via_token(login_token): | |||
sid = frappe.cache().get_value("login_token:{0}".format(login_token), expires=True) | |||
sid = xhiveframework.cache().get_value("login_token:{0}".format(login_token), expires=True) | |||
if not sid: | |||
frappe.respond_as_web_page(_("Invalid Request"), _("Invalid Login Token"), http_status_code=417) | |||
xhiveframework.respond_as_web_page(_("Invalid Request"), _("Invalid Login Token"), http_status_code=417) | |||
return | |||
frappe.local.form_dict.sid = sid | |||
frappe.local.login_manager = LoginManager() | |||
xhiveframework.local.form_dict.sid = sid | |||
xhiveframework.local.login_manager = LoginManager() | |||
redirect_post_login(desk_user = frappe.db.get_value("User", frappe.session.user, "user_type")=="System User") | |||
redirect_post_login(desk_user = xhiveframework.db.get_value("User", xhiveframework.session.user, "user_type")=="System User") |
@@ -1 +1 @@ | |||
# frappe -- https://github.com/frappe/frappe is installed via 'bench init' | |||
# xhiveframework -- https://github.com/xhiveframework/xhiveframework is installed via 'bench init' |
@@ -9,7 +9,7 @@ from datavalue_theme_14 import __version__ as version | |||
setup( | |||
name="datavalue_theme_14", | |||
version=version, | |||
description="Data Value Frappe 14 Theme", | |||
description="Data Value Xhiveframework 14 Theme", | |||
author="Abdo Hamoud", | |||
author_email="abdo.host@gmail.com", | |||
packages=find_packages(), | |||