From 1e5eeb79bca2a50b82a83bbf245f7d95cd48c9c6 Mon Sep 17 00:00:00 2001 From: Rushabh Mehta Date: Thu, 6 Feb 2014 18:33:25 +0530 Subject: [PATCH] added application selection pages and some fixes to toolbar --- .../core/page/applications/applications.js | 40 +- .../core/page/applications/applications.py | 3 +- webnotes/core/page/desktop/desktop.css | 26 +- webnotes/core/page/desktop/desktop.js | 167 ++- webnotes/core/page/finder/__init__.py | 0 webnotes/core/page/finder/finder.js | 205 --- webnotes/core/page/finder/finder.py | 0 webnotes/core/page/finder/finder.txt | 33 - .../core/page/modules_setup/modules_setup.js | 2 +- webnotes/desktop.json | 7 - webnotes/hooks.txt | 6 +- webnotes/public/build.json | 10 +- webnotes/public/css/{common.css => app.css} | 251 +--- webnotes/public/css/app_icon.css | 34 + webnotes/public/css/appframe.css | 131 ++ webnotes/public/css/avatar.css | 25 + webnotes/public/css/forms.css | 132 -- webnotes/public/css/navbar.css | 56 + webnotes/public/css/slickgrid.css | 21 + webnotes/public/css/typeahead.css | 45 - webnotes/public/js/lib/typeahead.js | 1142 ----------------- webnotes/public/js/wn/misc/user.js | 11 +- webnotes/public/js/wn/misc/utils.js | 13 + webnotes/public/js/wn/ui/app_icon.js | 26 + webnotes/public/js/wn/ui/appframe.js | 23 +- webnotes/public/js/wn/ui/listing.js | 10 +- webnotes/public/js/wn/ui/search.js | 93 -- webnotes/public/js/wn/ui/toolbar/search.js | 2 +- webnotes/public/js/wn/ui/toolbar/toolbar.js | 31 +- 29 files changed, 530 insertions(+), 2015 deletions(-) delete mode 100644 webnotes/core/page/finder/__init__.py delete mode 100644 webnotes/core/page/finder/finder.js delete mode 100644 webnotes/core/page/finder/finder.py delete mode 100644 webnotes/core/page/finder/finder.txt rename webnotes/public/css/{common.css => app.css} (58%) create mode 100644 webnotes/public/css/app_icon.css create mode 100644 webnotes/public/css/appframe.css create mode 100644 webnotes/public/css/avatar.css delete mode 100644 webnotes/public/css/forms.css create mode 100644 webnotes/public/css/navbar.css create mode 100644 webnotes/public/css/slickgrid.css delete mode 100644 webnotes/public/css/typeahead.css delete mode 100644 webnotes/public/js/lib/typeahead.js create mode 100644 webnotes/public/js/wn/ui/app_icon.js delete mode 100644 webnotes/public/js/wn/ui/search.js diff --git a/webnotes/core/page/applications/applications.js b/webnotes/core/page/applications/applications.js index 1310f85354..947f336af8 100644 --- a/webnotes/core/page/applications/applications.js +++ b/webnotes/core/page/applications/applications.js @@ -8,27 +8,43 @@ wn.pages['applications'].onload = function(wrapper) { wn.call({ method:"webnotes.core.page.applications.applications.get_app_list", callback: function(r) { - var $main = $(wrapper).find(".layout-main") + var $main = $(wrapper).find(".layout-main"); + if(!keys(r.message).length) { $main.html('
No Apps Installed
'); return; } $main.empty(); + + // search + $('
\ +
\ + \ +
\ +

').appendTo($main).find(".app-search").on("keyup", function() { + var val = $(this).val(); + $main.find(".app-listing").each(function() { + $(this).toggle($(this).attr("data-title").toLowerCase().indexOf(val)!==-1); + }); + }) + $.each(r.message, function(app_key, app) { - $.extend(app, app.app_icon); - $app = $($r('
\ -
\ - \ - \ - \ + wn.modules[app_key] = { + label: app.app_title, + icon: app.app_icon, + color: app.app_color, + is_app: true + } + app.app_icon = wn.ui.app_icon.get_html(app_key); + $app = $($r('
\ +
\ + %(app_icon)s\
\ -
\ +
\
\
\ -

%(app_title)s

\ +

%(app_title)s

\

%(app_description)s\
Publisher: %(app_publisher)s; Version: %(app_version)s

\
\ diff --git a/webnotes/core/page/applications/applications.py b/webnotes/core/page/applications/applications.py index f0790b1991..8a05eaf4c8 100644 --- a/webnotes/core/page/applications/applications.py +++ b/webnotes/core/page/applications/applications.py @@ -13,7 +13,8 @@ def get_app_list(): app_hooks = webnotes.get_hooks(app_name=app) for key in ("app_name", "app_title", "app_description", "app_icon", "app_publisher", "app_version", "app_url", "app_color"): - out[app][key] = app_hooks.get(key) + val = app_hooks.get(key) or [] + out[app][key] = val[0] if len(val) else "" if app in installed: out[app]["installed"] = 1 diff --git a/webnotes/core/page/desktop/desktop.css b/webnotes/core/page/desktop/desktop.css index 161ef81bfe..09e723c416 100644 --- a/webnotes/core/page/desktop/desktop.css +++ b/webnotes/core/page/desktop/desktop.css @@ -10,21 +10,6 @@ height: 100px; } -.case-border { - border-radius: 5px; - padding: 20px; - display: inline-block; - margin: auto; - text-align: center; -} - -.case-wrapper i { - font-size: 32px; - min-width: 32px; - color: #f8f8f8; - display: inline-block; -} - .case-label { color: white; padding-top: 5px; @@ -32,33 +17,26 @@ text-shadow: 0px 0px 10px rgba(0, 0, 0, 0.6); } - @media (max-width: 768px) { .case-wrapper { margin: 12px; width: 70px; height: 80px; } - .case-border { - padding: 12px; - } .case-label { padding-top: 2px; font-size: 85%; } } - - - /* Hover and click effects */ -.case-border:hover, .hover-effect { +.app-icon:hover, .hover-effect { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.2); -o-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.2); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.2); } -.case-border:active, .case-border:focus, .case-border-click { +.app-icon:active, .app-icon:focus, .case-border-click { -webkit-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.3); -o-box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.3); box-shadow: inset 0 3px 5px rgba(0, 0, 0, 0.3); diff --git a/webnotes/core/page/desktop/desktop.js b/webnotes/core/page/desktop/desktop.js index d0edf24842..1dbdbba70a 100644 --- a/webnotes/core/page/desktop/desktop.js +++ b/webnotes/core/page/desktop/desktop.js @@ -1,7 +1,21 @@ -wn.provide('wn.core.pages.desktop'); +wn.provide('wn.desktop'); -wn.core.pages.desktop.refresh = function() { - wn.core.pages.desktop.render(); +wn.pages['desktop'].onload = function(wrapper) { + // setup dialog + + // load desktop + wn.desktop.refresh(); +} + +wn.pages['desktop'].refresh = function(wrapper) { + wn.ui.toolbar.add_dropdown_button("File", wn._("All Applications"), function() { + wn.desktop.show_all_modules(); + }, 'icon-th'); + +} + +wn.desktop.refresh = function() { + wn.desktop.render(); $("#icon-grid").sortable({ update: function() { @@ -14,60 +28,149 @@ wn.core.pages.desktop.refresh = function() { }); } -wn.core.pages.desktop.render = function() { +wn.desktop.render = function() { + $("#icon-grid").empty(); + document.title = "Desktop"; var add_icon = function(m) { var module = wn.modules[m]; - if(!module || !module.link) + + if(!module || (!module.link && !module.onclick) || module.is_app) return; - if(!module.label) - module.label = m; - module.name = m; - module.label = wn._(module.label); - //module.gradient_css = wn.get_gradient_css(module.color, 45); - module._link = module.link.toLowerCase().replace("/", "-"); + if(module.link) + module._link = module.link.toLowerCase().replace("/", "-"); + + module.app_icon = wn.ui.app_icon.get_html(m); $module_icon = $(repl('
\ - \ -
\ - \ -
\ -
%(label)s
\ -
', module)).click(function() { + data-name="%(name)s" data-link="%(link)s">\ + \ + %(app_icon)s\ +
%(_label)s
\ +
', module)).click(module.link ? function() { var link = $(this).attr("data-link"); - if(link.substr(0, 1)==="/") { - window.open(link.substr(1)) + if(link) { + if(link.substr(0, 1)==="/") { + window.open(link.substr(1)) + } + wn.set_route(link); } - wn.set_route(link); - }).css({ + } : module.onclick).css({ cursor:"pointer" }).appendTo("#icon-grid"); } // modules var modules_list = wn.user.get_desktop_items(); + var user_list = wn.user.get_user_desktop_items(); $.each(modules_list, function(i, m) { - if(m!="Setup") - add_icon(m); + var module = wn.modules[m]; + if(module) { + if(!module.label) { + module.label = m; + } + module.name = m; + module._label = wn._(module.label); + + if(m!="Setup" && user_list.indexOf(m)!==-1) + add_icon(m); + } }) // setup if(user_roles.indexOf('System Manager')!=-1) add_icon('Setup') + // all applications + wn.modules["All Applications"] = { + icon: "icon-th", + label: "All Applications", + _label: wn._("All Applications"), + color: "#4aa3df", + link: "", + onclick: function() { + wn.desktop.show_all_modules(); + } + } + add_icon("All Applications") + // notifications - wn.core.pages.desktop.show_pending_notifications(); + wn.desktop.show_pending_notifications(); $(document).on("notification-update", function() { - wn.core.pages.desktop.show_pending_notifications(); + wn.desktop.show_pending_notifications(); }) } -wn.core.pages.desktop.show_pending_notifications = function() { +wn.desktop.show_all_modules = function() { + if(!wn.desktop.all_modules_dialog) { + var d = new wn.ui.Dialog({ + title: ' All Applications' + }); + + var desktop_items = wn.user.get_desktop_items(); + var user_desktop_items = wn.user.get_user_desktop_items(); + + $('') + .appendTo(d.body) + .on("keyup", function() { + var val = $(this).val(); + $(d.body).find(".list-group-item").each(function() { + $(this).toggle($(this).attr("data-label").toLowerCase().indexOf(val)!==-1); + }) + }); + $('

'+wn._("Checked items shown on desktop")+'

') + .appendTo(d.body); + $wrapper = $('
').appendTo(d.body); + + // list of applications (wn.user.get_desktop_items()) + $.each(keys(wn.modules).sort(), function(i, m) { + var module = wn.modules[m]; + if(module.link && desktop_items.indexOf(m)!==-1) { + module.app_icon = wn.ui.app_icon.get_html(m, true); + $(repl('
\ +
\ + \ +
\ + %(label)s\ + \ +
\ +
\ +
', module)).appendTo($wrapper); + } + }); + + // check shown items + $wrapper.find('[type="checkbox"]') + .on("click", function() { + // update user_desktop_items (when checked or un-checked) + var user_desktop_items = wn.user.get_user_desktop_items(); + var module = $(this).attr("data-name"); + if($(this).prop("checked")) { + user_desktop_items.push(module); + } else { + if(user_desktop_items.indexOf(module)!==-1) { + user_desktop_items.splice(user_desktop_items.indexOf(module), 1); + } + } + wn.defaults.set_default("_user_desktop_items", user_desktop_items); + wn.desktop.refresh(); + }) + .prop("checked", false); + $.each(user_desktop_items, function(i, m) { + $wrapper.find('[data-label="'+m+'"] [type="checkbox"]').prop("checked", true); + }) + wn.desktop.all_modules_dialog = d; + } + $(wn.desktop.all_modules_dialog.body).find(".desktop-app-search").val("").trigger("keyup"); + wn.desktop.all_modules_dialog.show(); +} + +wn.desktop.show_pending_notifications = function() { if (!wn.boot.notification_info.module_doctypes) { return; @@ -97,9 +200,3 @@ wn.core.pages.desktop.show_pending_notifications = function() { } }); } - -pscript.onload_desktop = function(wrapper) { - // load desktop - wn.core.pages.desktop.refresh(); -} - diff --git a/webnotes/core/page/finder/__init__.py b/webnotes/core/page/finder/__init__.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/webnotes/core/page/finder/finder.js b/webnotes/core/page/finder/finder.js deleted file mode 100644 index 37d8919df8..0000000000 --- a/webnotes/core/page/finder/finder.js +++ /dev/null @@ -1,205 +0,0 @@ -// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -// MIT License. See license.txt - -// todo -// - basic search in documents - -wn.pages['finder'].onload = function(wrapper) { - wn.ui.make_app_page({ - parent: wrapper, - title: wn._('Finder'), - single_column: true - }); - wrapper.appframe.add_module_icon("Finder"); - - var $body = $(wrapper).find(".layout-main").addClass("row"); - var start = 0, - doctype = null, - module = null; - - var get_col = function(colsize, icon, label, panel_class) { - return $('
\ -
\ -
\ - '+label+'\ - \ -
\ -
\ -
\ -
\ -
').appendTo($body); - } - - var $modules = get_col(3, "briefcase", wn._("Modules"), "default").find(".list-group"); - var $doctypes = get_col(3, "folder-close", wn._("Document Types"), "default").find(".list-group"); - - var $list = get_col(6, "file", wn._("Documents"), "info"); - var $doctype_label = $list.find(".col-heading") - - var $list_link = $list.find(".panel-heading .pull-right") - .append('') - .find(".list-link") - .click(function() { wn.set_route("List", doctype); }) - .toggle(false); - - var $new_link = $list.find(".panel-heading .pull-right") - .append(' ') - .find(".new-link") - .click(function() { new_doc(doctype); }) - .toggle(false); - - $list = $list.find(".list-group"); - - var reset_module = function() { - $doctypes.empty(); - $('
'+ - wn._("Select Module")+'
').appendTo($doctypes); - module = null; - reset_doctype(); - } - - var reset_doctype = function() { - $list.empty(); - $new_link.toggle(false); - $list_link.toggle(false); - $doctype_label.html(wn._("Documents")); - $('
'+ - wn._("Select Document Type")+'
').appendTo($list); - start=0; - } - - reset_module(); - - // modules - $.each(keys(wn.boot.notification_info.module_doctypes).sort(), function(i, module) { - $($r('%(module)s\ - ', - {module: module})).appendTo($modules); - }); - - $modules.on("click", ".module-link", function() { - // list doctypes - reset_module(); - - // select module - $modules.find(".list-group-item.active").removeClass("active"); - $(this).addClass("active"); - - // show doctypes - $doctypes.find(".row-select").remove(); - module = $(this).attr("data-module"); - - $.each(wn.boot.notification_info.module_doctypes[module].sort(), function(i, doctype) { - $($r('%(doctype)s\ - ', - {doctype: doctype})).appendTo($doctypes) - }); - }); - - - $doctypes.on("click", ".doctype-link", function() { - reset_doctype(); - - // select doctype - $doctypes.find(".list-group-item.active").removeClass("active"); - $(this).addClass("active"); - - doctype = $(this).attr("data-doctype"); - - // label - $doctype_label.html(wn._(doctype)); - - // new link - $new_link.toggle(!!wn.model.can_create(doctype)); - $list_link.toggle(!!wn.model.can_read(doctype)); - - render_list(); - }) - - $list.on("click", ".btn-more", function() { - start = start+20; - render_list(); - }); - - $list.on("click", ".btn-search", function() { - filter_list(); - }) - - $list.on("keypress", ".input-search", function(e) { - if(e.which===13) - filter_list(); - }) - - - var filter_list = function() { - start = 0; - $list.find(".document-item, .row-empty").remove(); - render_list(); - } - - var render_list = function() { - // remove more btn if any - $list.find(".row-more, .row-select").remove(); - - // loading indicator... - add_list_row('') - .addClass("row-loading text-center") - - var args = { - doctype: doctype, - fields: ["name", "modified", "owner"], - limit_start: start || 0, - limit_page_length: 20 - }; - - if($(".input-search").val()) { - args.filters = [[doctype, "name", "like", "%" + $(".input-search").val() + "%"]] - } - - wn.call({ - method: "webnotes.widgets.reportview.get", - args: args, - callback: function(r) { - $list.find(".row-loading").remove(); - - if(!$list.find(".input-search").length) { - // make search - $('
\ -
\ - \ - \ - \ - \ -
\ -
').appendTo($list); - } - - if(r.message.values) { - $.each(r.message.values, function(i, v) { - $($r('%(name)s\ - %(owner)s\ - %(modified)s', { - doctype: doctype, - name: v[1], - owner: v[0], - modified: comment_when(v[2]) - })).appendTo($list); - }) - if(r.message.values.length==20) { - add_list_row('More...').addClass("row-more text-center btn-more text-muted"); - } - } else { - add_list_row('').addClass("text-center text-muted row-empty"); - } - } - }) - } - - var add_list_row = function(html) { - return $(''+html+'').appendTo($list); - } -} \ No newline at end of file diff --git a/webnotes/core/page/finder/finder.py b/webnotes/core/page/finder/finder.py deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/webnotes/core/page/finder/finder.txt b/webnotes/core/page/finder/finder.txt deleted file mode 100644 index c1b917bae8..0000000000 --- a/webnotes/core/page/finder/finder.txt +++ /dev/null @@ -1,33 +0,0 @@ -[ - { - "creation": "2013-09-06 11:53:22", - "docstatus": 0, - "modified": "2013-09-06 16:33:10", - "modified_by": "Administrator", - "owner": "Administrator" - }, - { - "doctype": "Page", - "icon": "icon-folder-open", - "module": "Core", - "name": "__common__", - "page_name": "Finder", - "standard": "Yes", - "title": "Finder" - }, - { - "doctype": "Page Role", - "name": "__common__", - "parent": "finder", - "parentfield": "roles", - "parenttype": "Page", - "role": "All" - }, - { - "doctype": "Page", - "name": "finder" - }, - { - "doctype": "Page Role" - } -] \ No newline at end of file diff --git a/webnotes/core/page/modules_setup/modules_setup.js b/webnotes/core/page/modules_setup/modules_setup.js index 3500aad3d6..5bd6dea472 100644 --- a/webnotes/core/page/modules_setup/modules_setup.js +++ b/webnotes/core/page/modules_setup/modules_setup.js @@ -21,7 +21,7 @@ wn.modules_setup = { $('#modules-list').empty(); $.each(keys(wn.modules).sort(), function(i, m) { - if(m!="Setup") { + if(m!="Setup" && !wn.modules[m].is_app) { var $chk = $("") .prependTo($('

'+m+'

').appendTo("#modules-list")); if(!wn.boot.hidden_modules || wn.boot.hidden_modules.indexOf(m)==-1) { diff --git a/webnotes/desktop.json b/webnotes/desktop.json index 8cc39c523f..b54d13b74c 100644 --- a/webnotes/desktop.json +++ b/webnotes/desktop.json @@ -6,13 +6,6 @@ "link": "Calendar/Event", "type": "view" }, - "Finder": { - "color": "#14C7DE", - "icon": "icon-folder-open", - "label": "Finder", - "link": "finder", - "type": "page" - }, "Messages": { "color": "#9b59b6", "icon": "icon-comments", diff --git a/webnotes/hooks.txt b/webnotes/hooks.txt index 377302f4fd..02c550237b 100644 --- a/webnotes/hooks.txt +++ b/webnotes/hooks.txt @@ -1,8 +1,8 @@ app_name = webnotes -app_title = Web Notes +app_title = Frappe Framework app_publisher = Web Notes Technologies app_description = Full Stack Web Application Framwork in Python -app_icon = icon-cog +app_icon = assets/webnotes/images/frappe.svg app_version = 4.0.0-wip app_color = #3498db @@ -40,4 +40,4 @@ permission_query_conditions:Event = webnotes.core.doctype.event.event.get_permis has_permission:Event = webnotes.core.doctype.event.event.has_permission permission_query_conditions:ToDo = webnotes.core.doctype.todo.todo.get_permission_query_conditions -has_permission:ToDo = webnotes.core.doctype.todo.todo.has_permission \ No newline at end of file +has_permission:ToDo = webnotes.core.doctype.todo.todo.has_permission diff --git a/webnotes/public/build.json b/webnotes/public/build.json index 68a807e494..44088cafdb 100644 --- a/webnotes/public/build.json +++ b/webnotes/public/build.json @@ -34,8 +34,12 @@ "public/css/bootstrap.css", "public/css/bootstrap-responsive.css", "public/css/font-awesome.css", - "public/css/forms.css", - "public/css/common.css", + "public/css/app.css", + "public/css/appframe.css", + "public/css/app_icon.css", + "public/css/avatar.css", + "public/css/navbar.css", + "public/css/slickgrid.css", "public/css/tree_grid.css", "public/css/nprogress.css" ], @@ -74,6 +78,7 @@ "public/js/wn/ui/field_group.js", "public/js/wn/ui/dialog.js", "public/js/wn/ui/button.js", + "public/js/wn/ui/app_icon.js", "public/js/wn/model/model.js", "public/js/wn/model/meta.js", @@ -92,7 +97,6 @@ "public/js/wn/upload.js", "public/js/wn/ui/filters.js", - "public/js/wn/ui/search.js", "public/js/wn/ui/tree.js", "public/js/wn/ui/tags.js", diff --git a/webnotes/public/css/common.css b/webnotes/public/css/app.css similarity index 58% rename from webnotes/public/css/common.css rename to webnotes/public/css/app.css index d0bc1c77d3..d5de003aeb 100644 --- a/webnotes/public/css/common.css +++ b/webnotes/public/css/app.css @@ -166,196 +166,6 @@ div#freeze { width: 0px; } -/* appframe header */ - -.appframe { - padding-top: 15px; -} - -.appframe-titlebar { - min-height: 30px; - background-color: #e7e7e7; -} - -.titlebar-item { - padding-top: 10px; - padding-bottom: 10px; -} - -.titlebar-item h4 { - width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - margin: 0px; -} - -.titlebar-center-item { -} - -.appframe-header { - margin-bottom: 20px; -} - -.appframe-toolbar { - margin-bottom: 0px; -} - -.appframe-header .status-bar { - text-align: right; -} - - -/* fixed navbar in appframe */ - -.appframe .navbar { - margin-left: -15px; - margin-right: -15px; - margin-bottom: 0px; - border-radius: 0px; - border-bottom: 1px solid #e7e7e7; - min-height: 51px; -} - -.appframe .navbar-form select, -.appframe .navbar-form input, -.appframe .navbar-form button, -.appframe .navbar-form label { - margin-bottom: 5px; -} - -.appframe .navbar-form { - margin-bottom: 2px; - width: 100%; -} - -.appframe-iconbar, .appframe-form { - border-bottom: 1px solid #c7c7c7; -} - -.appframe-form { - padding: 5px 0px; -} - -.appframe-form input, .appframe-form select, .appframe-form label { - font-size: 90%; - padding: 4px; - margin: 3px 0px; -} - -.appframe-form .form-group { - margin-bottom: 0px; -} - -.appframe-form .form-control { - height: 28px; -} - -.iconbar { - display: inline-block; - padding: 9px 0px; -} - -.iconbar ul { - list-style: none; - margin: 0 0 0 0; - padding: 0 0 0 0; -} - -.iconbar li { - display: inline-block; - padding-left: 4px; - padding-right: 4px; -} - -.iconbar i { - margin-top: 4px; - margin-right: 4px; - color: #888; - cursor: pointer; - font-size: 16px; -} - -.iconbar i:hover { - color: #000; -} - -.iconbar i:active { - color: #5bc0de; -} - -.iconbar .appframe-iconbar-active i { - font-weight: bold; - color: orange; -} - - -.appframe-titlebar .title-text { - font-weight: bold; -} - -.appframe-footer { - margin-top: 15px; -} - -/* home icon in main nav */ - -.navbar-icon-home { - vertical-align: middle; -} - -.navbar-icon-home:hover, -.navbar-icon-home:focus, -.navbar-icon-home:active, -.navbar-icon-home-hover{ - opacity:1; - Filter:alpha(opacity=100); /* For IE8 and earlier */ -} - -.navbar .brand { - max-height: 15px; -} - -.navbar-brand { - min-height: 20px; - height: auto; -} - -.navbar #spinner { - display: block; - float: right; - width: 20px; - margin-bottom: -5px; - margin-top: 14px; - visibility: hidden; -} - -.navbar-new-comments { - margin: -3px 0px; - padding: 2px 5px; - min-width: 20px; - text-align: center; - display: inline-block; - border-radius: 2px; - color: #999999; - background-color: #333131; -} - -.navbar-new-comments:hover, -.navbar-new-comments:active, -.navbar-new-comments:focus { - color: #fff; -} - -.navbar-new-comments-true { - color: #fff; - background-color: #e74c3c; -} - - -.btn [class^="icon-"], .nav [class^="icon-"], .btn [class*=" icon-"], .nav [class*=" icon-"] { - display: inline-block; -} .badge-important { background-color: #e74c3c; @@ -394,58 +204,6 @@ div#freeze { white-space: nowrap; } -/* avatar */ - -.avatar { - display: inline-block; - vertical-align: middle; - border-radius: 50%; - overflow: hidden; - background-color: #ddd; - border: 1px solid #eee; -} - -.avatar img { - width: 100%; - height: auto; -} - -.avatar-small { - margin-right: 5px; - width: 30px; - height: 30px; -} - -.avatar-large { - margin-right: 10px; - width: 72px; - height: 72px; -} - -/* slickgrid */ - -.slick-cell { - font-size: 12px; -} - -.slick-header-column, .slick-cell { - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box; - box-sizing: content-box; -} - -.slick-headerrow-column { - background: #87ceeb; - text-overflow: clip; -} - -.slick-headerrow-column input { - margin: 0; - padding: 0; - width: 100%; - min-height: 20px; -} - .missing-image { background-color: #eee; display: table-cell; @@ -590,4 +348,11 @@ ul.linked-with-list li { padding: 2px 5px; margin-left: 15px; border-radius: 3px; - background-color: #ddd; \ No newline at end of file + background-color: #ddd; +} + +.print-preview { + padding: 50px 20px; + margin: 0px -15px; + box-shadow: 1px 1px 5px rgba(0,0,0,0.5); +} diff --git a/webnotes/public/css/app_icon.css b/webnotes/public/css/app_icon.css new file mode 100644 index 0000000000..373d931503 --- /dev/null +++ b/webnotes/public/css/app_icon.css @@ -0,0 +1,34 @@ +.app-icon { + border-radius: 5px; + padding: 20px; + display: inline-block; + margin: auto; + text-align: center; +} + + +.app-icon i { + font-size: 30px; + min-width: 30px; + color: #f8f8f8; + display: inline-block; +} + +.app-icon svg { + height: 30px; + width: 30px; +} + +.app-icon path { + fill: #f8f8f8; +} + +.app-icon-small { + padding: 12px; +} + +@media (max-width: 768px) { + .app-icon { + padding: 12px; + } +} diff --git a/webnotes/public/css/appframe.css b/webnotes/public/css/appframe.css new file mode 100644 index 0000000000..c5018dcbda --- /dev/null +++ b/webnotes/public/css/appframe.css @@ -0,0 +1,131 @@ +/* appframe header */ + +.appframe { + padding-top: 15px; +} + +.appframe-titlebar { + min-height: 30px; + background-color: #e7e7e7; +} + +.titlebar-item { + padding-top: 10px; + padding-bottom: 10px; +} + +.titlebar-item h4 { + width: 100%; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + margin: 0px; +} + +.titlebar-center-item { +} + +.appframe-header { + margin-bottom: 20px; +} + +.appframe-toolbar { + margin-bottom: 0px; +} + +.appframe-header .status-bar { + text-align: right; +} + + +/* fixed navbar in appframe */ + +.appframe .navbar { + margin-left: -15px; + margin-right: -15px; + margin-bottom: 0px; + border-radius: 0px; + border-bottom: 1px solid #e7e7e7; + min-height: 51px; +} + +.appframe .navbar-form select, +.appframe .navbar-form input, +.appframe .navbar-form button, +.appframe .navbar-form label { + margin-bottom: 5px; +} + +.appframe .navbar-form { + margin-bottom: 2px; + width: 100%; +} + +.appframe-iconbar, .appframe-form { + border-bottom: 1px solid #c7c7c7; +} + +.appframe-form { + padding: 5px 0px; +} + +.appframe-form input, .appframe-form select, .appframe-form label { + font-size: 90%; + padding: 4px; + margin: 3px 0px; +} + +.appframe-form .form-group { + margin-bottom: 0px; +} + +.appframe-form .form-control { + height: 28px; +} + +.iconbar { + display: inline-block; + padding: 9px 0px; +} + +.iconbar ul { + list-style: none; + margin: 0 0 0 0; + padding: 0 0 0 0; +} + +.iconbar li { + display: inline-block; + padding-left: 4px; + padding-right: 4px; +} + +.iconbar i { + margin-top: 4px; + margin-right: 4px; + color: #888; + cursor: pointer; + font-size: 16px; +} + +.iconbar i:hover { + color: #000; +} + +.iconbar i:active { + color: #5bc0de; +} + +.iconbar .appframe-iconbar-active i { + font-weight: bold; + color: orange; +} + + +.appframe-titlebar .title-text { + font-weight: bold; +} + +.appframe-footer { + margin-top: 15px; +} diff --git a/webnotes/public/css/avatar.css b/webnotes/public/css/avatar.css new file mode 100644 index 0000000000..a55cef4987 --- /dev/null +++ b/webnotes/public/css/avatar.css @@ -0,0 +1,25 @@ +.avatar { + display: inline-block; + vertical-align: middle; + border-radius: 50%; + overflow: hidden; + background-color: #ddd; + border: 1px solid #eee; +} + +.avatar img { + width: 100%; + height: auto; +} + +.avatar-small { + margin-right: 5px; + width: 30px; + height: 30px; +} + +.avatar-large { + margin-right: 10px; + width: 72px; + height: 72px; +} diff --git a/webnotes/public/css/forms.css b/webnotes/public/css/forms.css deleted file mode 100644 index 2980a851b9..0000000000 --- a/webnotes/public/css/forms.css +++ /dev/null @@ -1,132 +0,0 @@ -/* FORMS */ - -div.form-title { - /*background-color: #e0eeff;*/ - padding: 5px 19px 15px 19px; - border-bottom: 1px solid #eee; -} - -.appframe-titlebar .label { - vertical-align: middle; - margin-right: 7px; -} - -div.form-section-head { - border-top: 1px solid #ccc; - padding: 11px 23px 0px 23px; -} - -div.form-layout-row:first-child .form-section-head { - border-top: 0px solid #ccc !important; - margin-top: 0px; - padding-top: 0px; -} - -div.form-section-head h3 { - line-height: 20px; -} - -div.form-section-head hr { - margin: 9px 0px; -} - - -div.frm_print_wrapper { - background-color:#FFF; - border:1px solid #444; - padding: 40px; - - box-shadow:1px 1px 8px #229; - -moz-box-shadow: 1px 1px 8px #229; - -webkit-box-shadow: 1px 1px 8px #229; -} - -div.page_break { - margin: 24px 0px; - border-top: 1px dashed #888; -} - -div.dialog_frm { - position: relative; - margin: 10px; -} - -.top_cell { - height: 50px; -} - -div.attach_area { - padding: 8px; - margin: 8px; - background-color: #EEE; -} - -div.attach_area table { - width: 100%; -} - -.tablabel_normal { - margin: 0 4px 0 0; - padding: 3px 5px; - line-height: 1.3em; - display: inline; - cursor: pointer; -} - -.tablabel_selected { - margin: 0 4px 0 0; - padding: 3px 5px; - line-height: 1.3em; - font-weight: bold; - display: inline; - cursor: pointer; - color: #000; -} - -.sectionCell { - padding: 5px; - vertical-align: top; -} - -.code_area { - width: 80%; - margin: 8px; - padding: 4px; - background-color: #F8F8F8; - border: 1px solid #CCC; - overflow-x: auto; -} - -.code_text { - width: 100%; - height: 360px; - margin-top: 3px; - font-family: Courier, Fixed; - font-size: 12px; -} - -div.time_field select{ - display: inline; - margin: 2px; - width: 45px; -} - -/* sidebar */ - -div.sidebar-comment-wrapper input { - width: 70%; -} -div.sidebar-comment-message { - margin-top: 8px; - color: #777; -} - -div.sidebar-comment-text { - font-size: 12px; - font-weight: bold; - margin-top: 8px; - color: #444; -} -div.sidebar-comment-info { - color: #777; -} \ No newline at end of file diff --git a/webnotes/public/css/navbar.css b/webnotes/public/css/navbar.css new file mode 100644 index 0000000000..8fc6ad8251 --- /dev/null +++ b/webnotes/public/css/navbar.css @@ -0,0 +1,56 @@ +.navbar-icon-home { + vertical-align: middle; +} + +.navbar-icon-home:hover, +.navbar-icon-home:focus, +.navbar-icon-home:active, +.navbar-icon-home-hover{ + opacity:1; + Filter:alpha(opacity=100); /* For IE8 and earlier */ +} + +.navbar .brand { + max-height: 15px; +} + +.navbar-brand { + min-height: 20px; + height: auto; +} + +.navbar #spinner { + display: block; + float: right; + width: 20px; + margin-bottom: -5px; + margin-top: 14px; + visibility: hidden; +} + +.navbar-new-comments { + margin: -3px 0px; + padding: 2px 5px; + min-width: 20px; + text-align: center; + display: inline-block; + border-radius: 2px; + color: #999999; + background-color: #333131; +} + +.navbar-new-comments:hover, +.navbar-new-comments:active, +.navbar-new-comments:focus { + color: #fff; +} + +.navbar-new-comments-true { + color: #fff; + background-color: #e74c3c; +} + + +.btn [class^="icon-"], .nav [class^="icon-"], .btn [class*=" icon-"], .nav [class*=" icon-"] { + display: inline-block; +} diff --git a/webnotes/public/css/slickgrid.css b/webnotes/public/css/slickgrid.css new file mode 100644 index 0000000000..525b6c2f5f --- /dev/null +++ b/webnotes/public/css/slickgrid.css @@ -0,0 +1,21 @@ +.slick-cell { + font-size: 12px; +} + +.slick-header-column, .slick-cell { + -webkit-box-sizing: content-box; + -moz-box-sizing: content-box; + box-sizing: content-box; +} + +.slick-headerrow-column { + background: #87ceeb; + text-overflow: clip; +} + +.slick-headerrow-column input { + margin: 0; + padding: 0; + width: 100%; + min-height: 20px; +} \ No newline at end of file diff --git a/webnotes/public/css/typeahead.css b/webnotes/public/css/typeahead.css deleted file mode 100644 index 485cd8e578..0000000000 --- a/webnotes/public/css/typeahead.css +++ /dev/null @@ -1,45 +0,0 @@ -.typeahead, -.tt-query, -.tt-hint { -} - -.tt-hint { - color: #999; -} - -.tt-dropdown-menu { - width: 100%; - margin-top: 3px; - padding: 3px 0; - background-color: #fff; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, 0.2); - -webkit-border-radius: 8px; - -moz-border-radius: 8px; - border-radius: 8px; - -webkit-box-shadow: 0 5px 10px rgba(0,0,0,.2); - -moz-box-shadow: 0 5px 10px rgba(0,0,0,.2); - box-shadow: 0 5px 10px rgba(0,0,0,.2); -} - -.tt-suggestion { - padding: 3px 20px; -} - -.tt-suggestion.tt-is-under-cursor { - color: #fff; - background-color: #0097cf; -} - -.tt-suggestion.tt-is-under-cursor .text-muted { - color: #ddd; -} - -.input-group input.tt-query { - border-top-left-radius: 4px !important; - border-bottom-left-radius: 4px !important; -} - -.tt-suggestion p { - margin: 0; -} diff --git a/webnotes/public/js/lib/typeahead.js b/webnotes/public/js/lib/typeahead.js deleted file mode 100644 index 03849c1188..0000000000 --- a/webnotes/public/js/lib/typeahead.js +++ /dev/null @@ -1,1142 +0,0 @@ -/*! - * typeahead.js 0.9.3 - * https://github.com/twitter/typeahead - * Copyright 2013 Twitter, Inc. and other contributors; Licensed MIT - */ - -(function($) { - var VERSION = "0.9.3"; - var utils = { - isMsie: function() { - var match = /(msie) ([\w.]+)/i.exec(navigator.userAgent); - return match ? parseInt(match[2], 10) : false; - }, - isBlankString: function(str) { - return !str || /^\s*$/.test(str); - }, - escapeRegExChars: function(str) { - return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&"); - }, - isString: function(obj) { - return typeof obj === "string"; - }, - isNumber: function(obj) { - return typeof obj === "number"; - }, - isArray: $.isArray, - isFunction: $.isFunction, - isObject: $.isPlainObject, - isUndefined: function(obj) { - return typeof obj === "undefined"; - }, - bind: $.proxy, - bindAll: function(obj) { - var val; - for (var key in obj) { - $.isFunction(val = obj[key]) && (obj[key] = $.proxy(val, obj)); - } - }, - indexOf: function(haystack, needle) { - for (var i = 0; i < haystack.length; i++) { - if (haystack[i] === needle) { - return i; - } - } - return -1; - }, - each: $.each, - map: $.map, - filter: $.grep, - every: function(obj, test) { - var result = true; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (!(result = test.call(null, val, key, obj))) { - return false; - } - }); - return !!result; - }, - some: function(obj, test) { - var result = false; - if (!obj) { - return result; - } - $.each(obj, function(key, val) { - if (result = test.call(null, val, key, obj)) { - return false; - } - }); - return !!result; - }, - mixin: $.extend, - getUniqueId: function() { - var counter = 0; - return function() { - return counter++; - }; - }(), - defer: function(fn) { - setTimeout(fn, 0); - }, - debounce: function(func, wait, immediate) { - var timeout, result; - return function() { - var context = this, args = arguments, later, callNow; - later = function() { - timeout = null; - if (!immediate) { - result = func.apply(context, args); - } - }; - callNow = immediate && !timeout; - clearTimeout(timeout); - timeout = setTimeout(later, wait); - if (callNow) { - result = func.apply(context, args); - } - return result; - }; - }, - throttle: function(func, wait) { - var context, args, timeout, result, previous, later; - previous = 0; - later = function() { - previous = new Date(); - timeout = null; - result = func.apply(context, args); - }; - return function() { - var now = new Date(), remaining = wait - (now - previous); - context = this; - args = arguments; - if (remaining <= 0) { - clearTimeout(timeout); - timeout = null; - previous = now; - result = func.apply(context, args); - } else if (!timeout) { - timeout = setTimeout(later, remaining); - } - return result; - }; - }, - tokenizeQuery: function(str) { - return $.trim(str).toLowerCase().split(/[\s]+/); - }, - tokenizeText: function(str) { - return $.trim(str).toLowerCase().split(/[\s\-_]+/); - }, - getProtocol: function() { - return location.protocol; - }, - noop: function() {} - }; - var EventTarget = function() { - var eventSplitter = /\s+/; - return { - on: function(events, callback) { - var event; - if (!callback) { - return this; - } - this._callbacks = this._callbacks || {}; - events = events.split(eventSplitter); - while (event = events.shift()) { - this._callbacks[event] = this._callbacks[event] || []; - this._callbacks[event].push(callback); - } - return this; - }, - trigger: function(events, data) { - var event, callbacks; - if (!this._callbacks) { - return this; - } - events = events.split(eventSplitter); - while (event = events.shift()) { - if (callbacks = this._callbacks[event]) { - for (var i = 0; i < callbacks.length; i += 1) { - callbacks[i].call(this, { - type: event, - data: data - }); - } - } - } - return this; - } - }; - }(); - var EventBus = function() { - var namespace = "typeahead:"; - function EventBus(o) { - if (!o || !o.el) { - $.error("EventBus initialized without el"); - } - this.$el = $(o.el); - } - utils.mixin(EventBus.prototype, { - trigger: function(type) { - var args = [].slice.call(arguments, 1); - this.$el.trigger(namespace + type, args); - } - }); - return EventBus; - }(); - var PersistentStorage = function() { - var ls, methods; - try { - ls = window.localStorage; - ls.setItem("~~~", "!"); - ls.removeItem("~~~"); - } catch (err) { - ls = null; - } - function PersistentStorage(namespace) { - this.prefix = [ "__", namespace, "__" ].join(""); - this.ttlKey = "__ttl__"; - this.keyMatcher = new RegExp("^" + this.prefix); - } - if (ls && window.JSON) { - methods = { - _prefix: function(key) { - return this.prefix + key; - }, - _ttlKey: function(key) { - return this._prefix(key) + this.ttlKey; - }, - get: function(key) { - if (this.isExpired(key)) { - this.remove(key); - } - return decode(ls.getItem(this._prefix(key))); - }, - set: function(key, val, ttl) { - if (utils.isNumber(ttl)) { - ls.setItem(this._ttlKey(key), encode(now() + ttl)); - } else { - ls.removeItem(this._ttlKey(key)); - } - return ls.setItem(this._prefix(key), encode(val)); - }, - remove: function(key) { - ls.removeItem(this._ttlKey(key)); - ls.removeItem(this._prefix(key)); - return this; - }, - clear: function() { - var i, key, keys = [], len = ls.length; - for (i = 0; i < len; i++) { - if ((key = ls.key(i)).match(this.keyMatcher)) { - keys.push(key.replace(this.keyMatcher, "")); - } - } - for (i = keys.length; i--; ) { - this.remove(keys[i]); - } - return this; - }, - isExpired: function(key) { - var ttl = decode(ls.getItem(this._ttlKey(key))); - return utils.isNumber(ttl) && now() > ttl ? true : false; - } - }; - } else { - methods = { - get: utils.noop, - set: utils.noop, - remove: utils.noop, - clear: utils.noop, - isExpired: utils.noop - }; - } - utils.mixin(PersistentStorage.prototype, methods); - return PersistentStorage; - function now() { - return new Date().getTime(); - } - function encode(val) { - return JSON.stringify(utils.isUndefined(val) ? null : val); - } - function decode(val) { - return JSON.parse(val); - } - }(); - var RequestCache = function() { - function RequestCache(o) { - utils.bindAll(this); - o = o || {}; - this.sizeLimit = o.sizeLimit || 10; - this.cache = {}; - this.cachedKeysByAge = []; - } - utils.mixin(RequestCache.prototype, { - get: function(url) { - return this.cache[url]; - }, - set: function(url, resp) { - var requestToEvict; - if (this.cachedKeysByAge.length === this.sizeLimit) { - requestToEvict = this.cachedKeysByAge.shift(); - delete this.cache[requestToEvict]; - } - this.cache[url] = resp; - this.cachedKeysByAge.push(url); - } - }); - return RequestCache; - }(); - var Transport = function() { - var pendingRequestsCount = 0, pendingRequests = {}, maxPendingRequests, requestCache; - function Transport(o) { - utils.bindAll(this); - o = utils.isString(o) ? { - url: o - } : o; - requestCache = requestCache || new RequestCache(); - maxPendingRequests = utils.isNumber(o.maxParallelRequests) ? o.maxParallelRequests : maxPendingRequests || 6; - this.url = o.url; - this.wildcard = o.wildcard || "%QUERY"; - this.filter = o.filter; - this.replace = o.replace; - this.ajaxSettings = { - type: "get", - cache: o.cache, - timeout: o.timeout, - dataType: o.dataType || "json", - beforeSend: o.beforeSend - }; - this._get = (/^throttle$/i.test(o.rateLimitFn) ? utils.throttle : utils.debounce)(this._get, o.rateLimitWait || 300); - } - utils.mixin(Transport.prototype, { - _get: function(url, cb) { - var that = this; - if (belowPendingRequestsThreshold()) { - this._sendRequest(url).done(done); - } else { - this.onDeckRequestArgs = [].slice.call(arguments, 0); - } - function done(resp) { - var data = that.filter ? that.filter(resp) : resp; - cb && cb(data); - requestCache.set(url, resp); - } - }, - _sendRequest: function(url) { - var that = this, jqXhr = pendingRequests[url]; - if (!jqXhr) { - incrementPendingRequests(); - jqXhr = pendingRequests[url] = $.ajax(url, this.ajaxSettings).always(always); - } - return jqXhr; - function always() { - decrementPendingRequests(); - pendingRequests[url] = null; - if (that.onDeckRequestArgs) { - that._get.apply(that, that.onDeckRequestArgs); - that.onDeckRequestArgs = null; - } - } - }, - get: function(query, cb) { - var that = this, encodedQuery = encodeURIComponent(query || ""), url, resp; - cb = cb || utils.noop; - url = this.replace ? this.replace(this.url, encodedQuery) : this.url.replace(this.wildcard, encodedQuery); - if (resp = requestCache.get(url)) { - utils.defer(function() { - cb(that.filter ? that.filter(resp) : resp); - }); - } else { - this._get(url, cb); - } - return !!resp; - } - }); - return Transport; - function incrementPendingRequests() { - pendingRequestsCount++; - } - function decrementPendingRequests() { - pendingRequestsCount--; - } - function belowPendingRequestsThreshold() { - return pendingRequestsCount < maxPendingRequests; - } - }(); - var Dataset = function() { - var keys = { - thumbprint: "thumbprint", - protocol: "protocol", - itemHash: "itemHash", - adjacencyList: "adjacencyList" - }; - function Dataset(o) { - utils.bindAll(this); - if (utils.isString(o.template) && !o.engine) { - $.error("no template engine specified"); - } - if (!o.local && !o.prefetch && !o.remote) { - $.error("one of local, prefetch, or remote is required"); - } - this.name = o.name || utils.getUniqueId(); - this.limit = o.limit || 5; - this.minLength = o.minLength || 1; - this.header = o.header; - this.footer = o.footer; - this.valueKey = o.valueKey || "value"; - this.template = compileTemplate(o.template, o.engine, this.valueKey); - this.local = o.local; - this.prefetch = o.prefetch; - this.remote = o.remote; - this.itemHash = {}; - this.adjacencyList = {}; - this.storage = o.name ? new PersistentStorage(o.name) : null; - } - utils.mixin(Dataset.prototype, { - _processLocalData: function(data) { - this._mergeProcessedData(this._processData(data)); - }, - _loadPrefetchData: function(o) { - var that = this, thumbprint = VERSION + (o.thumbprint || ""), storedThumbprint, storedProtocol, storedItemHash, storedAdjacencyList, isExpired, deferred; - if (this.storage) { - storedThumbprint = this.storage.get(keys.thumbprint); - storedProtocol = this.storage.get(keys.protocol); - storedItemHash = this.storage.get(keys.itemHash); - storedAdjacencyList = this.storage.get(keys.adjacencyList); - } - isExpired = storedThumbprint !== thumbprint || storedProtocol !== utils.getProtocol(); - o = utils.isString(o) ? { - url: o - } : o; - o.ttl = utils.isNumber(o.ttl) ? o.ttl : 24 * 60 * 60 * 1e3; - if (storedItemHash && storedAdjacencyList && !isExpired) { - this._mergeProcessedData({ - itemHash: storedItemHash, - adjacencyList: storedAdjacencyList - }); - deferred = $.Deferred().resolve(); - } else { - deferred = $.getJSON(o.url).done(processPrefetchData); - } - return deferred; - function processPrefetchData(data) { - var filteredData = o.filter ? o.filter(data) : data, processedData = that._processData(filteredData), itemHash = processedData.itemHash, adjacencyList = processedData.adjacencyList; - if (that.storage) { - that.storage.set(keys.itemHash, itemHash, o.ttl); - that.storage.set(keys.adjacencyList, adjacencyList, o.ttl); - that.storage.set(keys.thumbprint, thumbprint, o.ttl); - that.storage.set(keys.protocol, utils.getProtocol(), o.ttl); - } - that._mergeProcessedData(processedData); - } - }, - _transformDatum: function(datum) { - var value = utils.isString(datum) ? datum : datum[this.valueKey], tokens = datum.tokens || utils.tokenizeText(value), item = { - value: value, - tokens: tokens - }; - if (utils.isString(datum)) { - item.datum = {}; - item.datum[this.valueKey] = datum; - } else { - item.datum = datum; - } - item.tokens = utils.filter(item.tokens, function(token) { - return !utils.isBlankString(token); - }); - item.tokens = utils.map(item.tokens, function(token) { - return token.toLowerCase(); - }); - return item; - }, - _processData: function(data) { - var that = this, itemHash = {}, adjacencyList = {}; - utils.each(data, function(i, datum) { - var item = that._transformDatum(datum), id = utils.getUniqueId(item.value); - itemHash[id] = item; - utils.each(item.tokens, function(i, token) { - var character = token.charAt(0), adjacency = adjacencyList[character] || (adjacencyList[character] = [ id ]); - !~utils.indexOf(adjacency, id) && adjacency.push(id); - }); - }); - return { - itemHash: itemHash, - adjacencyList: adjacencyList - }; - }, - _mergeProcessedData: function(processedData) { - var that = this; - utils.mixin(this.itemHash, processedData.itemHash); - utils.each(processedData.adjacencyList, function(character, adjacency) { - var masterAdjacency = that.adjacencyList[character]; - that.adjacencyList[character] = masterAdjacency ? masterAdjacency.concat(adjacency) : adjacency; - }); - }, - _getLocalSuggestions: function(terms) { - var that = this, firstChars = [], lists = [], shortestList, suggestions = []; - utils.each(terms, function(i, term) { - var firstChar = term.charAt(0); - !~utils.indexOf(firstChars, firstChar) && firstChars.push(firstChar); - }); - utils.each(firstChars, function(i, firstChar) { - var list = that.adjacencyList[firstChar]; - if (!list) { - return false; - } - lists.push(list); - if (!shortestList || list.length < shortestList.length) { - shortestList = list; - } - }); - if (lists.length < firstChars.length) { - return []; - } - utils.each(shortestList, function(i, id) { - var item = that.itemHash[id], isCandidate, isMatch; - isCandidate = utils.every(lists, function(list) { - return ~utils.indexOf(list, id); - }); - isMatch = isCandidate && utils.every(terms, function(term) { - return utils.some(item.tokens, function(token) { - return token.indexOf(term) === 0; - }); - }); - isMatch && suggestions.push(item); - }); - return suggestions; - }, - initialize: function() { - var deferred; - this.local && this._processLocalData(this.local); - this.transport = this.remote ? new Transport(this.remote) : null; - deferred = this.prefetch ? this._loadPrefetchData(this.prefetch) : $.Deferred().resolve(); - this.local = this.prefetch = this.remote = null; - this.initialize = function() { - return deferred; - }; - return deferred; - }, - getSuggestions: function(query, cb) { - var that = this, terms, suggestions, cacheHit = false; - if (query.length < this.minLength) { - return; - } - terms = utils.tokenizeQuery(query); - suggestions = this._getLocalSuggestions(terms).slice(0, this.limit); - if (suggestions.length < this.limit && this.transport) { - cacheHit = this.transport.get(query, processRemoteData); - } - !cacheHit && cb && cb(suggestions); - function processRemoteData(data) { - suggestions = suggestions.slice(0); - utils.each(data, function(i, datum) { - var item = that._transformDatum(datum), isDuplicate; - isDuplicate = utils.some(suggestions, function(suggestion) { - return item.value === suggestion.value; - }); - !isDuplicate && suggestions.push(item); - return suggestions.length < that.limit; - }); - cb && cb(suggestions); - } - } - }); - return Dataset; - function compileTemplate(template, engine, valueKey) { - var renderFn, compiledTemplate; - if (utils.isFunction(template)) { - renderFn = template; - } else if (utils.isString(template)) { - compiledTemplate = engine.compile(template); - renderFn = utils.bind(compiledTemplate.render, compiledTemplate); - } else { - renderFn = function(context) { - return "

" + context[valueKey] + "

"; - }; - } - return renderFn; - } - }(); - var InputView = function() { - function InputView(o) { - var that = this; - utils.bindAll(this); - this.specialKeyCodeMap = { - 9: "tab", - 27: "esc", - 37: "left", - 39: "right", - 13: "enter", - 38: "up", - 40: "down" - }; - this.$hint = $(o.hint); - this.$input = $(o.input).on("blur.tt", this._handleBlur).on("focus.tt", this._handleFocus).on("keydown.tt", this._handleSpecialKeyEvent); - if (!utils.isMsie()) { - this.$input.on("input.tt", this._compareQueryToInputValue); - } else { - this.$input.on("keydown.tt keypress.tt cut.tt paste.tt", function($e) { - if (that.specialKeyCodeMap[$e.which || $e.keyCode]) { - return; - } - utils.defer(that._compareQueryToInputValue); - }); - } - this.query = this.$input.val(); - this.$overflowHelper = buildOverflowHelper(this.$input); - } - utils.mixin(InputView.prototype, EventTarget, { - _handleFocus: function() { - this.trigger("focused"); - }, - _handleBlur: function() { - this.trigger("blured"); - }, - _handleSpecialKeyEvent: function($e) { - var keyName = this.specialKeyCodeMap[$e.which || $e.keyCode]; - keyName && this.trigger(keyName + "Keyed", $e); - }, - _compareQueryToInputValue: function() { - var inputValue = this.getInputValue(), isSameQuery = compareQueries(this.query, inputValue), isSameQueryExceptWhitespace = isSameQuery ? this.query.length !== inputValue.length : false; - if (isSameQueryExceptWhitespace) { - this.trigger("whitespaceChanged", { - value: this.query - }); - } else if (!isSameQuery) { - this.trigger("queryChanged", { - value: this.query = inputValue - }); - } - }, - destroy: function() { - this.$hint.off(".tt"); - this.$input.off(".tt"); - this.$hint = this.$input = this.$overflowHelper = null; - }, - focus: function() { - this.$input.focus(); - }, - blur: function() { - this.$input.blur(); - }, - getQuery: function() { - return this.query; - }, - setQuery: function(query) { - this.query = query; - }, - getInputValue: function() { - return this.$input.val(); - }, - setInputValue: function(value, silent) { - this.$input.val(value); - !silent && this._compareQueryToInputValue(); - }, - getHintValue: function() { - return this.$hint.val(); - }, - setHintValue: function(value) { - this.$hint.val(value); - }, - getLanguageDirection: function() { - return (this.$input.css("direction") || "ltr").toLowerCase(); - }, - isOverflow: function() { - this.$overflowHelper.text(this.getInputValue()); - return this.$overflowHelper.width() > this.$input.width(); - }, - isCursorAtEnd: function() { - var valueLength = this.$input.val().length, selectionStart = this.$input[0].selectionStart, range; - if (utils.isNumber(selectionStart)) { - return selectionStart === valueLength; - } else if (document.selection) { - range = document.selection.createRange(); - range.moveStart("character", -valueLength); - return valueLength === range.text.length; - } - return true; - } - }); - return InputView; - function buildOverflowHelper($input) { - return $("").css({ - position: "absolute", - left: "-9999px", - visibility: "hidden", - whiteSpace: "nowrap", - fontFamily: $input.css("font-family"), - fontSize: $input.css("font-size"), - fontStyle: $input.css("font-style"), - fontVariant: $input.css("font-variant"), - fontWeight: $input.css("font-weight"), - wordSpacing: $input.css("word-spacing"), - letterSpacing: $input.css("letter-spacing"), - textIndent: $input.css("text-indent"), - textRendering: $input.css("text-rendering"), - textTransform: $input.css("text-transform") - }).insertAfter($input); - } - function compareQueries(a, b) { - a = (a || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " "); - b = (b || "").replace(/^\s*/g, "").replace(/\s{2,}/g, " "); - return a === b; - } - }(); - var DropdownView = function() { - var html = { - suggestionsList: '' - }, css = { - suggestionsList: { - display: "block" - }, - suggestion: { - whiteSpace: "nowrap", - cursor: "pointer" - }, - suggestionChild: { - whiteSpace: "normal" - } - }; - function DropdownView(o) { - utils.bindAll(this); - this.isOpen = false; - this.isEmpty = true; - this.isMouseOverDropdown = false; - this.$menu = $(o.menu).on("mouseenter.tt", this._handleMouseenter).on("mouseleave.tt", this._handleMouseleave).on("click.tt", ".tt-suggestion", this._handleSelection).on("mouseover.tt", ".tt-suggestion", this._handleMouseover); - } - utils.mixin(DropdownView.prototype, EventTarget, { - _handleMouseenter: function() { - this.isMouseOverDropdown = true; - }, - _handleMouseleave: function() { - this.isMouseOverDropdown = false; - }, - _handleMouseover: function($e) { - var $suggestion = $($e.currentTarget); - this._getSuggestions().removeClass("tt-is-under-cursor"); - $suggestion.addClass("tt-is-under-cursor"); - }, - _handleSelection: function($e) { - var $suggestion = $($e.currentTarget); - this.trigger("suggestionSelected", extractSuggestion($suggestion)); - }, - _show: function() { - this.$menu.css("display", "block"); - }, - _hide: function() { - this.$menu.hide(); - }, - _moveCursor: function(increment) { - var $suggestions, $cur, nextIndex, $underCursor; - if (!this.isVisible()) { - return; - } - $suggestions = this._getSuggestions(); - $cur = $suggestions.filter(".tt-is-under-cursor"); - $cur.removeClass("tt-is-under-cursor"); - nextIndex = $suggestions.index($cur) + increment; - nextIndex = (nextIndex + 1) % ($suggestions.length + 1) - 1; - if (nextIndex === -1) { - this.trigger("cursorRemoved"); - return; - } else if (nextIndex < -1) { - nextIndex = $suggestions.length - 1; - } - $underCursor = $suggestions.eq(nextIndex).addClass("tt-is-under-cursor"); - this._ensureVisibility($underCursor); - this.trigger("cursorMoved", extractSuggestion($underCursor)); - }, - _getSuggestions: function() { - return this.$menu.find(".tt-suggestions > .tt-suggestion"); - }, - _ensureVisibility: function($el) { - var menuHeight = this.$menu.height() + parseInt(this.$menu.css("paddingTop"), 10) + parseInt(this.$menu.css("paddingBottom"), 10), menuScrollTop = this.$menu.scrollTop(), elTop = $el.position().top, elBottom = elTop + $el.outerHeight(true); - if (elTop < 0) { - this.$menu.scrollTop(menuScrollTop + elTop); - } else if (menuHeight < elBottom) { - this.$menu.scrollTop(menuScrollTop + (elBottom - menuHeight)); - } - }, - destroy: function() { - this.$menu.off(".tt"); - this.$menu = null; - }, - isVisible: function() { - return this.isOpen && !this.isEmpty; - }, - closeUnlessMouseIsOverDropdown: function() { - if (!this.isMouseOverDropdown) { - this.close(); - } - }, - close: function() { - if (this.isOpen) { - this.isOpen = false; - this.isMouseOverDropdown = false; - this._hide(); - this.$menu.find(".tt-suggestions > .tt-suggestion").removeClass("tt-is-under-cursor"); - this.trigger("closed"); - } - }, - open: function() { - if (!this.isOpen) { - this.isOpen = true; - !this.isEmpty && this._show(); - this.trigger("opened"); - } - }, - setLanguageDirection: function(dir) { - var ltrCss = { - left: "0", - right: "auto" - }, rtlCss = { - left: "auto", - right: " 0" - }; - dir === "ltr" ? this.$menu.css(ltrCss) : this.$menu.css(rtlCss); - }, - moveCursorUp: function() { - this._moveCursor(-1); - }, - moveCursorDown: function() { - this._moveCursor(+1); - }, - getSuggestionUnderCursor: function() { - var $suggestion = this._getSuggestions().filter(".tt-is-under-cursor").first(); - return $suggestion.length > 0 ? extractSuggestion($suggestion) : null; - }, - getFirstSuggestion: function() { - var $suggestion = this._getSuggestions().first(); - return $suggestion.length > 0 ? extractSuggestion($suggestion) : null; - }, - renderSuggestions: function(dataset, suggestions) { - var datasetClassName = "tt-dataset-" + dataset.name, - wrapper = '
%body
', compiledHtml, $suggestionsList, $dataset = this.$menu.find("." + datasetClassName), elBuilder, fragment, $el; - if ($dataset.length === 0) { - $suggestionsList = $(html.suggestionsList).css(css.suggestionsList); - $dataset = $("
").addClass(datasetClassName).append(dataset.header).append($suggestionsList).append(dataset.footer).appendTo(this.$menu); - } - if (suggestions.length > 0) { - this.isEmpty = false; - this.isOpen && this._show(); - elBuilder = document.createElement("div"); - fragment = document.createDocumentFragment(); - - utils.each(suggestions, function(i, suggestion) { - suggestion.dataset = dataset.name; - compiledHtml = dataset.template(suggestion.datum); - $(".tt-suggestion[data-value='"+suggestion.datum.value+"']").remove(); - elBuilder.innerHTML = wrapper.replace("%body", compiledHtml).replace("%value", suggestion.datum.value); - $el = $(elBuilder.firstChild).css(css.suggestion).data("suggestion", suggestion); - $el.children().each(function() { - $(this).css(css.suggestionChild); - }); - fragment.appendChild($el[0]); - }); - $dataset.show().find(".tt-suggestions").html(fragment); - } else { - this.clearSuggestions(dataset.name); - } - this.trigger("suggestionsRendered"); - }, - clearSuggestions: function(datasetName) { - var $datasets = datasetName ? this.$menu.find(".tt-dataset-" + datasetName) : this.$menu.find('[class^="tt-dataset-"]'), $suggestions = $datasets.find(".tt-suggestions"); - $datasets.hide(); - $suggestions.empty(); - if (this._getSuggestions().length === 0) { - this.isEmpty = true; - this._hide(); - } - } - }); - return DropdownView; - function extractSuggestion($el) { - return $el.data("suggestion"); - } - }(); - var TypeaheadView = function() { - var html = { - wrapper: '', - hint: '', - dropdown: '' - }, css = { - wrapper: { - position: "relative", - display: "block" - }, - hint: { - position: "absolute", - top: "0", - left: "0", - borderColor: "transparent", - boxShadow: "none" - }, - query: { - position: "relative", - verticalAlign: "top", - backgroundColor: "transparent" - }, - dropdown: { - position: "absolute", - top: "100%", - left: "0", - zIndex: "100", - display: "none" - } - }; - if (utils.isMsie()) { - utils.mixin(css.query, { - backgroundImage: "url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7)" - }); - } - if (utils.isMsie() && utils.isMsie() <= 7) { - utils.mixin(css.wrapper, { - display: "inline", - zoom: "1" - }); - utils.mixin(css.query, { - marginTop: "-1px" - }); - } - function TypeaheadView(o) { - var $menu, $input, $hint; - utils.bindAll(this); - this.$node = buildDomStructure(o.input); - this.datasets = o.datasets; - this.dir = null; - this.eventBus = o.eventBus; - $menu = this.$node.find(".tt-dropdown-menu"); - $input = this.$node.find(".tt-query"); - $hint = this.$node.find(".tt-hint"); - this.dropdownView = new DropdownView({ - menu: $menu - }).on("suggestionSelected", this._handleSelection).on("cursorMoved", this._clearHint).on("cursorMoved", this._setInputValueToSuggestionUnderCursor).on("cursorRemoved", this._setInputValueToQuery).on("cursorRemoved", this._updateHint).on("suggestionsRendered", this._updateHint).on("opened", this._updateHint).on("closed", this._clearHint).on("opened closed", this._propagateEvent); - this.inputView = new InputView({ - input: $input, - hint: $hint - }).on("focused", this._openDropdown).on("blured", this._closeDropdown).on("blured", this._setInputValueToQuery).on("enterKeyed tabKeyed", this._handleSelection).on("queryChanged", this._clearHint).on("queryChanged", this._clearSuggestions).on("queryChanged", this._getSuggestions).on("whitespaceChanged", this._updateHint).on("queryChanged whitespaceChanged", this._openDropdown).on("queryChanged whitespaceChanged", this._setLanguageDirection).on("escKeyed", this._closeDropdown).on("escKeyed", this._setInputValueToQuery).on("tabKeyed upKeyed downKeyed", this._managePreventDefault).on("upKeyed downKeyed", this._moveDropdownCursor).on("upKeyed downKeyed", this._openDropdown).on("tabKeyed leftKeyed rightKeyed", this._autocomplete); - } - utils.mixin(TypeaheadView.prototype, EventTarget, { - _managePreventDefault: function(e) { - var $e = e.data, hint, inputValue, preventDefault = false; - switch (e.type) { - case "tabKeyed": - hint = this.inputView.getHintValue(); - inputValue = this.inputView.getInputValue(); - preventDefault = hint && hint !== inputValue; - break; - - case "upKeyed": - case "downKeyed": - preventDefault = !$e.shiftKey && !$e.ctrlKey && !$e.metaKey; - break; - } - preventDefault && $e.preventDefault(); - }, - _setLanguageDirection: function() { - var dir = this.inputView.getLanguageDirection(); - if (dir !== this.dir) { - this.dir = dir; - this.$node.css("direction", dir); - this.dropdownView.setLanguageDirection(dir); - } - }, - _updateHint: function() { - var suggestion = this.dropdownView.getFirstSuggestion(), hint = suggestion ? suggestion.value : null, dropdownIsVisible = this.dropdownView.isVisible(), inputHasOverflow = this.inputView.isOverflow(), inputValue, query, escapedQuery, beginsWithQuery, match; - if (hint && dropdownIsVisible && !inputHasOverflow) { - inputValue = this.inputView.getInputValue(); - query = inputValue.replace(/\s{2,}/g, " ").replace(/^\s+/g, ""); - escapedQuery = utils.escapeRegExChars(query); - beginsWithQuery = new RegExp("^(?:" + escapedQuery + ")(.*$)", "i"); - match = beginsWithQuery.exec(hint); - this.inputView.setHintValue(inputValue + (match ? match[1] : "")); - } - }, - _clearHint: function() { - this.inputView.setHintValue(""); - }, - _clearSuggestions: function() { - this.dropdownView.clearSuggestions(); - }, - _setInputValueToQuery: function() { - this.inputView.setInputValue(this.inputView.getQuery()); - }, - _setInputValueToSuggestionUnderCursor: function(e) { - var suggestion = e.data; - this.inputView.setInputValue(suggestion.value, true); - }, - _openDropdown: function() { - this.dropdownView.open(); - }, - _closeDropdown: function(e) { - this.dropdownView[e.type === "blured" ? "closeUnlessMouseIsOverDropdown" : "close"](); - }, - _moveDropdownCursor: function(e) { - var $e = e.data; - if (!$e.shiftKey && !$e.ctrlKey && !$e.metaKey) { - this.dropdownView[e.type === "upKeyed" ? "moveCursorUp" : "moveCursorDown"](); - } - }, - _handleSelection: function(e) { - var byClick = e.type === "suggestionSelected", suggestion = byClick ? e.data : this.dropdownView.getSuggestionUnderCursor(); - if (suggestion) { - this.inputView.setInputValue(suggestion.value); - byClick ? this.inputView.focus() : e.data.preventDefault(); - byClick && utils.isMsie() ? utils.defer(this.dropdownView.close) : this.dropdownView.close(); - this.eventBus.trigger("selected", suggestion.datum, suggestion.dataset); - } - }, - _getSuggestions: function() { - var that = this, query = this.inputView.getQuery(); - if (utils.isBlankString(query)) { - return; - } - utils.each(this.datasets, function(i, dataset) { - dataset.getSuggestions(query, function(suggestions) { - if (query === that.inputView.getQuery()) { - that.dropdownView.renderSuggestions(dataset, suggestions); - } - }); - }); - }, - _autocomplete: function(e) { - var isCursorAtEnd, ignoreEvent, query, hint, suggestion; - if (e.type === "rightKeyed" || e.type === "leftKeyed") { - isCursorAtEnd = this.inputView.isCursorAtEnd(); - ignoreEvent = this.inputView.getLanguageDirection() === "ltr" ? e.type === "leftKeyed" : e.type === "rightKeyed"; - if (!isCursorAtEnd || ignoreEvent) { - return; - } - } - query = this.inputView.getQuery(); - hint = this.inputView.getHintValue(); - if (hint !== "" && query !== hint) { - suggestion = this.dropdownView.getFirstSuggestion(); - this.inputView.setInputValue(suggestion.value); - this.eventBus.trigger("autocompleted", suggestion.datum, suggestion.dataset); - } - }, - _propagateEvent: function(e) { - this.eventBus.trigger(e.type); - }, - destroy: function() { - this.inputView.destroy(); - this.dropdownView.destroy(); - destroyDomStructure(this.$node); - this.$node = null; - }, - setQuery: function(query) { - this.inputView.setQuery(query); - this.inputView.setInputValue(query); - this._clearHint(); - this._clearSuggestions(); - this._getSuggestions(); - } - }); - return TypeaheadView; - function buildDomStructure(input) { - var $wrapper = $(html.wrapper), $dropdown = $(html.dropdown), $input = $(input), $hint = $(html.hint); - $wrapper = $wrapper.css(css.wrapper); - $dropdown = $dropdown.css(css.dropdown); - $hint.css(css.hint).css({ - backgroundAttachment: $input.css("background-attachment"), - backgroundClip: $input.css("background-clip"), - backgroundColor: $input.css("background-color"), - backgroundImage: $input.css("background-image"), - backgroundOrigin: $input.css("background-origin"), - backgroundPosition: $input.css("background-position"), - backgroundRepeat: $input.css("background-repeat"), - backgroundSize: $input.css("background-size") - }); - $input.data("ttAttrs", { - dir: $input.attr("dir"), - autocomplete: $input.attr("autocomplete"), - spellcheck: $input.attr("spellcheck"), - style: $input.attr("style") - }); - $input.addClass("tt-query").attr({ - autocomplete: "off", - spellcheck: false - }).css(css.query); - try { - !$input.attr("dir") && $input.attr("dir", "auto"); - } catch (e) {} - return $input.wrap($wrapper).parent().prepend($hint).append($dropdown); - } - function destroyDomStructure($node) { - var $input = $node.find(".tt-query"); - utils.each($input.data("ttAttrs"), function(key, val) { - utils.isUndefined(val) ? $input.removeAttr(key) : $input.attr(key, val); - }); - $input.detach().removeData("ttAttrs").removeClass("tt-query").insertAfter($node); - $node.remove(); - } - }(); - (function() { - var cache = {}, viewKey = "ttView", methods; - methods = { - initialize: function(datasetDefs) { - var datasets; - datasetDefs = utils.isArray(datasetDefs) ? datasetDefs : [ datasetDefs ]; - if (datasetDefs.length === 0) { - $.error("no datasets provided"); - } - datasets = utils.map(datasetDefs, function(o) { - var dataset = cache[o.name] ? cache[o.name] : new Dataset(o); - if (o.name) { - cache[o.name] = dataset; - } - return dataset; - }); - return this.each(initialize); - function initialize() { - var $input = $(this), deferreds, eventBus = new EventBus({ - el: $input - }); - deferreds = utils.map(datasets, function(dataset) { - return dataset.initialize(); - }); - $input.data(viewKey, new TypeaheadView({ - input: $input, - eventBus: eventBus = new EventBus({ - el: $input - }), - datasets: datasets - })); - $.when.apply($, deferreds).always(function() { - utils.defer(function() { - eventBus.trigger("initialized"); - }); - }); - } - }, - destroy: function() { - return this.each(destroy); - function destroy() { - var $this = $(this), view = $this.data(viewKey); - if (view) { - view.destroy(); - $this.removeData(viewKey); - } - } - }, - setQuery: function(query) { - return this.each(setQuery); - function setQuery() { - var view = $(this).data(viewKey); - view && view.setQuery(query); - } - } - }; - jQuery.fn.typeahead = function(method) { - if (methods[method]) { - return methods[method].apply(this, [].slice.call(arguments, 1)); - } else { - return methods.initialize.apply(this, arguments); - } - }; - })(); -})(window.jQuery); \ No newline at end of file diff --git a/webnotes/public/js/wn/misc/user.js b/webnotes/public/js/wn/misc/user.js index ffd2068d72..4b026d8195 100644 --- a/webnotes/public/js/wn/misc/user.js +++ b/webnotes/public/js/wn/misc/user.js @@ -71,8 +71,8 @@ $.extend(wn.user, { if(modules_list) { // add missing modules - they will be hidden anyways by the view - $.each(wn.modules, function(m, data) { - if(modules_list.indexOf(m)==-1) { + $.each(wn.modules, function(m, module) { + if(module.link && modules_list.indexOf(m)==-1) { modules_list.push(m); } }); @@ -122,6 +122,13 @@ $.extend(wn.user, { return modules_list; }, + get_user_desktop_items: function() { + var user_list = wn.defaults.get_default("_user_desktop_items"); + if(!user_list) { + user_list = ["Calendar", "To Do", "Activity", "Messages"]; + } + return user_list; + }, is_report_manager: function() { return wn.user.has_role(['Administrator', 'System Manager', 'Report Manager']); }, diff --git a/webnotes/public/js/wn/misc/utils.js b/webnotes/public/js/wn/misc/utils.js index f1f3b62cdd..e717635efd 100644 --- a/webnotes/public/js/wn/misc/utils.js +++ b/webnotes/public/js/wn/misc/utils.js @@ -200,6 +200,19 @@ wn.utils = { return arr; }, + dict: function(keys,values) { + // make dictionaries from keys and values + var out = []; + $.each(values, function(row_idx, row) { + var new_row = {}; + $.each(keys, function(key_idx, key) { + new_row[key] = row[key_idx]; + }) + out.push(new_row); + }); + return out; + }, + sum: function(list) { return list.reduce(function(previous_value, current_value) { return flt(previous_value) + flt(current_value); }, 0.0); }, diff --git a/webnotes/public/js/wn/ui/app_icon.js b/webnotes/public/js/wn/ui/app_icon.js new file mode 100644 index 0000000000..1ca0b1ec8c --- /dev/null +++ b/webnotes/public/js/wn/ui/app_icon.js @@ -0,0 +1,26 @@ +// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors +// MIT License. See license.txt + + +wn.provide("wn.ui") +wn.ui.app_icon = { + get_html: function(app, small) { + var icon = wn.modules[app].icon; + var color = wn.modules[app].color; + if(icon.split(".").slice(-1)[0]==="svg") { + $.ajax({ + url: icon, + dataType: "text", + async: false, + success: function(data) { + icon = data; + } + }) + icon = ''+icon+''; + } else { + icon = '' + } + return '
'+icon+'
' + } +} \ No newline at end of file diff --git a/webnotes/public/js/wn/ui/appframe.js b/webnotes/public/js/wn/ui/appframe.js index aba4c3f0cf..43b55924a4 100644 --- a/webnotes/public/js/wn/ui/appframe.js +++ b/webnotes/public/js/wn/ui/appframe.js @@ -230,29 +230,8 @@ wn.ui.AppFrame = Class.extend({ return this.iconbar.add_btn("1", icon, wn._(label), click); }, - // appframe::navbar links add_dropdown_button: function(parent, label, click, icon) { - var menu = this.get_menu(parent); - if(menu.find("li:not(.custom-menu)").length && !menu.find(".divider").length) { - this.add_menu_divider(menu); - } - - return $('
  • '+label+'
  • ') - .insertBefore(menu.find(".divider")) - .find("a") - .click(function() { - click(); - }); - }, - get_menu: function(label) { - return $("#navbar-" + label.toLowerCase()); - }, - add_menu_divider: function(menu) { - menu = typeof menu == "string" ? - this.get_menu(menu) : menu; - - $('
  • ').prependTo(menu); + wn.ui.toolbar.add_dropdown_button(parent, label, click, icon); }, // appframe::form diff --git a/webnotes/public/js/wn/ui/listing.js b/webnotes/public/js/wn/ui/listing.js index 603dc33956..f9d44b8b79 100644 --- a/webnotes/public/js/wn/ui/listing.js +++ b/webnotes/public/js/wn/ui/listing.js @@ -294,15 +294,7 @@ wn.ui.Listing = Class.extend({ get_values_from_response: function(data) { // make dictionaries from keys and values if(data.keys) { - var values = []; - $.each(data.values, function(row_idx, row) { - var new_row = {}; - $.each(data.keys, function(key_idx, key) { - new_row[key] = row[key_idx]; - }) - values.push(new_row); - }); - return values; + return wn.utils.dict(data.keys, data.values); } else { return data; } diff --git a/webnotes/public/js/wn/ui/search.js b/webnotes/public/js/wn/ui/search.js deleted file mode 100644 index 95f2cebfed..0000000000 --- a/webnotes/public/js/wn/ui/search.js +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2013, Web Notes Technologies Pvt. Ltd. and Contributors -// MIT License. See license.txt - -// search widget - -// options: doctype, callback, query (if applicable) -wn.ui.Search = Class.extend({ - init: function(opts) { - $.extend(this, opts); - var me = this; - wn.model.with_doctype(this.doctype, function(r) { - me.make(); - me.dialog.show(); - me.list.$w.find('.list-filters input[type="text"]').focus(); - }); - }, - make: function() { - var me = this; - this.dialog = new wn.ui.Dialog({ - title: this.doctype + ' Search', - width: 500 - }); - var parent = $('
    ') - .appendTo(this.dialog.body) - .find(".col-md-12") - this.list = new wn.ui.Listing({ - parent: parent, - appframe: this.dialog.appframe, - new_doctype: this.doctype, - doctype: this.doctype, - type: "GET", - method: 'webnotes.widgets.reportview.get', - show_filters: true, - style: 'compact', - get_args: function() { - if(me.query) { - me.page_length = 50; // there has to be a better way :( - return { - query: me.query - } - } else { - return { - doctype: me.doctype, - fields: me.get_fields(), - filters: me.list.filter_list.get_filters(), - docstatus: ['0','1'] - } - } - }, - render_row: function(parent, data) { - $ln = $('' - + data.name +'') - .appendTo(parent) - .click(function() { - var val = $(this).attr('data-name'); - me.dialog.hide(); - if(me.callback) - me.callback(val); - else - wn.set_route('Form', me.doctype, val); - return false; - }); - - // other values - $.each(data, function(key, value) { - if(key!=="name") { - $("") - .html(value) - .css({"margin-left": "15px", "display": "block"}) - .appendTo(parent); - } - }) - if(this.data.length==1) { - $ln.click(); - } - } - }); - this.list.filter_list.add_filter(this.doctype, 'name', 'like'); - this.list.run(); - }, - get_fields: function() { - var me = this; - var fields = [ '`tab' + me.doctype + '`.name']; - $.each((wn.model.get("DocType", me.doctype)[0].search_fields || "").split(","), - function(i, field) { - if(strip(field)) { - fields.push('`tab' + me.doctype + '`.' + strip(field)); - } - } - ) - return fields; - } -}) \ No newline at end of file diff --git a/webnotes/public/js/wn/ui/toolbar/search.js b/webnotes/public/js/wn/ui/toolbar/search.js index 2559100215..0c91ca293a 100644 --- a/webnotes/public/js/wn/ui/toolbar/search.js +++ b/webnotes/public/js/wn/ui/toolbar/search.js @@ -6,7 +6,7 @@ wn.ui.toolbar.Search = wn.ui.toolbar.SelectorDialog.extend({ this._super({ title: wn._("Search"), execute: function(val) { - new wn.ui.Search({doctype:val}); + wn.set_route("List", val); }, help: wn._("Shortcut") + ": Ctrl+G" }); diff --git a/webnotes/public/js/wn/ui/toolbar/toolbar.js b/webnotes/public/js/wn/ui/toolbar/toolbar.js index 8166ad7ab7..2de7ab359f 100644 --- a/webnotes/public/js/wn/ui/toolbar/toolbar.js +++ b/webnotes/public/js/wn/ui/toolbar/toolbar.js @@ -118,6 +118,8 @@ wn.ui.toolbar.Toolbar = Class.extend({ wn.ui.toolbar.new_dialog = new wn.ui.toolbar.NewDialog(); wn.ui.toolbar.search = new wn.ui.toolbar.Search(); wn.ui.toolbar.report = new wn.ui.toolbar.Report(); + $('.navbar .nav:first').append('
  • '); $('.navbar .nav:first').append('
  • \ '+wn._('New')+'...
  • \ -
  • \ - '+wn._('Search')+'...
  • \
  • \ '+wn._('Report')+'...
  • \ \ @@ -167,8 +167,35 @@ wn.ui.toolbar.Toolbar = Class.extend({ $('#toolbar-user').append('
  • \ '+wn._('Logout')+'
  • '); } + }); +$.extend(wn.ui.toolbar, { + add_dropdown_button: function(parent, label, click, icon) { + var menu = wn.ui.toolbar.get_menu(parent); + if(menu.find("li:not(.custom-menu)").length && !menu.find(".divider").length) { + wn.ui.toolbar.add_menu_divider(menu); + } + + return $('
  • '+label+'
  • ') + .insertBefore(menu.find(".divider")) + .find("a") + .click(function() { + click(); + }); + }, + get_menu: function(label) { + return $("#navbar-" + label.toLowerCase()); + }, + add_menu_divider: function(menu) { + menu = typeof menu == "string" ? + wn.ui.toolbar.get_menu(menu) : menu; + + $('
  • ').prependTo(menu); + }, +}) + wn.ui.toolbar.update_notifications = function() { var total = 0; var doctypes = keys(wn.boot.notification_info.open_count_doctype).sort();