[framework] [cleanup] desktop, todo, messages, modules setup moved to framework

This commit is contained in:
Rushabh Mehta 2013-04-03 15:21:44 +05:30
parent 85adc07b5a
commit 27c4079ff9
27 changed files with 116 additions and 980 deletions

79
config.json Normal file
View File

@ -0,0 +1,79 @@
{
"modules": {
"Selling": {
"link": "selling-home",
"color": "#3f4901",
"icon": "icon-tag",
"type": "module"
},
"Accounts": {
"link": "accounts-home",
"color": "#025770",
"icon": "icon-money",
"type": "module"
},
"Stock": {
"type": "module",
"link": "stock-home",
"color": "#a66a02",
"icon": "icon-truck"
},
"Buying": {
"type": "module",
"link": "buying-home",
"color": "#8F0222",
"icon": "icon-shopping-cart"
},
"Support": {
"type": "module",
"link": "support-home",
"color": "#410169",
"icon": "icon-phone"
},
"Projects": {
"type": "module",
"link": "projects-home",
"color": "#473b7f",
"icon": "icon-tasks"
},
"Manufacturing": {
"type": "module",
"link": "manufacturing-home",
"color": "#590116",
"icon": "icon-magic"
},
"Website": {
"type": "module",
"link": "website-home",
"color": "#968c00",
"icon": "icon-globe"
},
"HR": {
"type": "module",
"link": "hr-home",
"color": "#018d6c",
"label": "Human Resources",
"icon": "icon-group"
},
"Setup": {
"type": "setup",
"link": "Setup",
"color": "#484848",
"icon": "icon-wrench"
},
"Activity": {
"type": "page",
"link": "activity",
"color": "#633501",
"icon": "icon-play",
"label": "Activity"
},
"Knowledge Base": {
"type": "page",
"link": "questions",
"color": "#01372b",
"label": "Knowledge Base",
"icon": "icon-question-sign"
}
}
}

View File

@ -1,21 +1,32 @@
[
{
"owner": "Administrator",
"creation": "2012-06-14 18:44:56",
"docstatus": 0,
"creation": "2012-02-29 11:59:13",
"modified": "2013-04-03 14:59:38",
"modified_by": "Administrator",
"modified": "2012-02-29 12:11:46"
"owner": "Administrator"
},
{
"name": "__common__",
"title": "Activity",
"module": "Home",
"doctype": "Page",
"module": "Home",
"name": "__common__",
"page_name": "activity",
"standard": "Yes"
"standard": "Yes",
"title": "Activity"
},
{
"name": "activity",
"doctype": "Page"
"doctype": "Page Role",
"name": "__common__",
"parent": "activity",
"parentfield": "roles",
"parenttype": "Page",
"role": "All"
},
{
"doctype": "Page",
"name": "activity"
},
{
"doctype": "Page Role"
}
]

View File

@ -0,0 +1,11 @@
import webnotes, json
import webnotes.utils
def execute():
modules = webnotes.get_config().modules
ml = json.loads(webnotes.conn.get_global("modules_list") or "[]")
webnotes.conn.set_global("hidden_modules",
json.dumps(list(set(modules.keys()).difference(set(ml)))))

View File

@ -234,5 +234,5 @@ patch_list = [
'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Classic") # 2013-04-02',
'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Modern") # 2013-04-02',
'execute:webnotes.reload_doc("selling", "Print Format", "Quotation Spartan") # 2013-04-02',
"patches.april_2013.p04_reverse_modules_list",
]

View File

@ -13,7 +13,6 @@
"public/js/all-app.min.js": [
"app/public/js/startup.js",
"app/public/js/conf.js",
"app/public/js/modules.js",
"app/public/js/toolbar.js",
"app/public/js/feature_setup.js",
"app/public/js/utils.js",

View File

@ -1,105 +0,0 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
wn.home_page = "desktop";
wn.provide("wn.module_page");
$.extend(wn.modules, {
"Selling": {
link: "selling-home",
color: "#3f4901",
icon: "icon-tag"
},
"Accounts": {
link: "accounts-home",
color: "#025770",
icon: "icon-money"
},
"Stock": {
link: "stock-home",
color: "#a66a02",
icon: "icon-truck"
},
"Buying": {
link: "buying-home",
color: "#8F0222",
icon: "icon-shopping-cart"
},
"Support": {
link: "support-home",
color: "#410169",
icon: "icon-phone"
},
"Projects": {
link: "projects-home",
color: "#473b7f",
icon: "icon-tasks"
},
"Manufacturing": {
link: "manufacturing-home",
color: "#590116",
icon: "icon-magic"
},
"Website": {
link: "website-home",
color: "#968c00",
icon: "icon-globe"
},
"HR": {
link: "hr-home",
color: "#018d6c",
label: wn._("Human Resources"),
icon: "icon-group"
},
"Setup": {
link: "Setup",
color: "#484848",
icon: "icon-wrench"
},
"Activity": {
link: "activity",
color: "#633501",
icon: "icon-play",
label: wn._("Activity"),
},
"To Do": {
link: "todo",
color: "#febf04",
label: wn._("To Do"),
icon: "icon-check"
},
"Calendar": {
link: "Calendar/Event",
color: "#026584",
label: wn._("Calendar"),
icon: "icon-calendar"
},
"Messages": {
link: "messages",
color: "#8d016e",
label: wn._("Messages"),
icon: "icon-comments"
},
"Knowledge Base": {
link: "questions",
color: "#01372b",
label: wn._("Knowledge Base"),
icon: "icon-question-sign"
},
});
wn.provide('erpnext.module_page');

View File

@ -31,11 +31,7 @@ erpnext.startup.start = function() {
if(user != 'Guest'){
erpnext.setup_mousetrap();
// always allow apps
wn.boot.profile.allow_modules = wn.boot.profile.allow_modules.concat(
['To Do', 'Knowledge Base', 'Calendar', 'Activity', 'Messages'])
// setup toolbar
erpnext.toolbar.setup();

View File

@ -74,12 +74,11 @@ erpnext.toolbar.add_modules = function() {
}
// add to dropdown
for(var i in modules_list) {
var m = modules_list[i]
if(m!='Setup' && wn.boot.profile.allow_modules.indexOf(m)!=-1 && wn.modules[m]) {
$.each(modules_list,function(i, m) {
if(m!='Setup') {
$('.navbar .modules').append(_get_list_item(m));
}
}
})
// setup for system manager
if(user_roles.indexOf("System Manager")!=-1) {

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,14 +0,0 @@
<div class="layout-wrapper">
<a class="close" onclick="window.history.back();">&times;</a>
<h1>Modules Setup</h1>
<hr>
<div class="help" style="width: 300px; float: right">
Select checkbox to show / hide module.
</div>
<div id="modules-list">
</div>
<div>
<button class="btn btn-small btn-primary" id="modules-update"
onclick="wn.pages.modules_setup.update()">Update</button>
</div>
</div>

View File

@ -1,51 +0,0 @@
wn.require('lib/js/lib/jquery/jquery.ui.sortable.js');
$.extend(wn.pages.modules_setup, {
modules: ['Activity', 'Accounts', 'Selling', 'Buying', 'Stock', 'Manufacturing', 'Projects',
'Support', 'HR', 'Website', 'To Do', 'Messages', 'Calendar', 'Knowledge Base'],
onload: function(wrapper) {
wn.pages.modules_setup.refresh_page(JSON.parse(wn.boot.modules_list || "[]"));
},
refresh_page: function(ml) {
$('#modules-list').empty();
// Hide Setup and Dashboard modules
ml.indexOf('Setup')!=-1 && ml.splice(ml.indexOf('Setup'), 1);
// checked modules
for(i in ml) {
$('#modules-list').append(repl('<p style="cursor:move;">\
<input type="checkbox" data-module="%(m)s"> \
%(m)s</p>', {m:ml[i]}));
}
$('#modules-list [data-module]').attr('checked', true);
// unchecked modules
var all = wn.pages.modules_setup.modules;
for(i in all) {
if(!$('#modules-list [data-module="'+all[i]+'"]').length) {
$('#modules-list').append(repl('<p style="cursor:move;">\
<input type="checkbox" data-module="%(m)s"> \
%(m)s</p>', {m:all[i]}));
}
}
},
update: function() {
var ml = [];
$('#modules-list [data-module]').each(function() {
if($(this).attr('checked'))
ml.push($(this).attr('data-module'));
});
wn.call({
method: 'setup.page.modules_setup.modules_setup.update',
args: {
ml: JSON.stringify(ml)
},
callback: function(r) {
},
btn: $('#modules-update').get(0)
});
}
});

View File

@ -1,9 +0,0 @@
from __future__ import unicode_literals
import webnotes
@webnotes.whitelist()
def update(arg=None):
"""update modules"""
webnotes.conn.set_global('modules_list', webnotes.form_dict['ml'])
webnotes.msgprint('Updated')
webnotes.clear_cache()

View File

@ -1,32 +0,0 @@
[
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-06-14 15:07:28",
"modified_by": "Administrator",
"modified": "2012-10-04 16:55:31"
},
{
"name": "__common__",
"title": "Modules Setup",
"module": "Setup",
"doctype": "Page",
"page_name": "modules_setup",
"standard": "Yes"
},
{
"parent": "modules_setup",
"name": "__common__",
"doctype": "Page Role",
"parenttype": "Page",
"role": "System Manager",
"parentfield": "roles"
},
{
"name": "modules_setup",
"doctype": "Page"
},
{
"doctype": "Page Role"
}
]

View File

@ -26,9 +26,7 @@ def boot_session(bootinfo):
import webnotes.model.doctype
bootinfo['notification_settings'] = webnotes.doc("Notification Control",
"Notification Control").get_values()
bootinfo['modules_list'] = webnotes.conn.get_global('modules_list')
# if no company, show a dialog box to create a new company
bootinfo['setup_complete'] = webnotes.conn.sql("""select name from
tabCompany limit 1""") and 'Yes' or 'No'

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,32 +0,0 @@
#message-post-text {
}
#message-list {
}
.message {
padding: 7px;
padding-left: 17px;
border-bottom: 1px solid #ccc;
}
.message-mark {
margin-left: -17px;
width: 9px;
position: absolute;
height: 30px;
}
.message .help {
margin-bottom: 0px;
padding-bottom: 0px;
color: #888;
font-size: 11px;
}
.message-other {
}
.message-self {
background-color: #eee;
}

View File

@ -1,214 +0,0 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
wn.provide('erpnext.messages');
wn.pages.messages.onload = function(wrapper) {
wn.ui.make_app_page({
parent: wrapper,
title: "Messages"
});
$('<div><div class="avatar avatar-large">\
<img id="avatar-image" src="lib/images/ui/avatar.png"></div>\
<h3 style="display: inline-block" id="message-title">Everyone</h3>\
</div><hr>\
<div id="post-message">\
<textarea style="width: 100%; height: 24px;"></textarea>\
<div><button class="btn">Post</button></div><hr>\
</div>\
<div class="all-messages"></div>').appendTo($(wrapper).find('.layout-main-section'));
wrapper.appframe.add_home_breadcrumb();
wrapper.appframe.add_breadcrumb(wn.modules["Messages"].icon);
erpnext.messages = new erpnext.Messages(wrapper);
erpnext.toolbar.set_new_comments(0);
}
$(wn.pages.messages).bind('show', function() {
// remove alerts
$('#alert-container .alert').remove();
erpnext.toolbar.set_new_comments(0);
erpnext.messages.show();
setTimeout("erpnext.messages.refresh()", 17000);
})
erpnext.Messages = Class.extend({
init: function(wrapper) {
this.wrapper = wrapper;
this.show_active_users();
this.make_post_message();
this.make_list();
//this.update_messages('reset'); //Resets notification icons
},
make_post_message: function() {
var me = this;
$('#post-message textarea').keydown(function(e) {
if(e.which==13) {
$('#post-message .btn').click();
return false;
}
});
$('#post-message .btn').click(function() {
var txt = $('#post-message textarea').val();
if(txt) {
wn.call({
module:'utilities',
page:'messages',
method:'post',
args: {
txt: txt,
contact: me.contact
},
callback:function(r,rt) {
$('#post-message textarea').val('')
me.list.run();
},
btn: this
});
}
});
},
show: function() {
var contact = this.get_contact() || this.contact || user;
$('#message-title').html(contact==user ? "Everyone" :
wn.user_info(contact).fullname)
$('#avatar-image').attr("src", wn.utils.get_file_link(wn.user_info(contact).image));
$("#show-everyone").toggle(contact!=user);
$("#post-message button").text(contact==user ? "Post Publicly" : "Post to user")
this.contact = contact;
this.list.opts.args.contact = contact;
this.list.run();
},
// check for updates every 5 seconds if page is active
refresh: function() {
setTimeout("erpnext.messages.refresh()", 17000);
if(wn.container.page.label != 'Messages') return;
this.show();
},
get_contact: function() {
var route = location.hash;
if(route.indexOf('/')!=-1) {
var name = decodeURIComponent(route.split('/')[1]);
if(name.indexOf('__at__')!=-1) {
name = name.replace('__at__', '@');
}
return name;
}
},
make_list: function() {
this.list = new wn.ui.Listing({
parent: $(this.wrapper).find('.all-messages'),
method: 'utilities.page.messages.messages.get_list',
args: {
contact: null
},
hide_refresh: true,
no_loading: true,
render_row: function(wrapper, data) {
$(wrapper).removeClass('list-row');
data.creation = dateutil.comment_when(data.creation);
data.comment_by_fullname = wn.user_info(data.owner).fullname;
data.image = wn.utils.get_file_link(wn.user_info(data.owner).image);
data.mark_html = "";
data.reply_html = '';
if(data.owner==user) {
data.cls = 'message-self';
data.comment_by_fullname = 'You';
} else {
data.cls = 'message-other';
}
// delete
data.delete_html = "";
if(data.owner==user || data.comment.indexOf("assigned to")!=-1) {
data.delete_html = repl('<a class="close" \
onclick="erpnext.messages.delete(this)"\
data-name="%(name)s">&times;</a>', data);
}
if(data.owner==data.comment_docname && data.parenttype!="Assignment") {
data.mark_html = "<div class='message-mark' title='Public'\
style='background-color: green'></div>"
}
wrapper.innerHTML = repl('<div class="message %(cls)s">%(mark_html)s\
<span class="avatar avatar-small"><img src="%(image)s"></span><b>%(comment)s</b>\
%(delete_html)s\
<div class="help">by %(comment_by_fullname)s, %(creation)s</div>\
</div>\
<div style="clear: both;"></div>', data);
}
});
},
delete: function(ele) {
$(ele).parent().css('opacity', 0.6);
wn.call({
method:'utilities.page.messages.messages.delete',
args: {name : $(ele).attr('data-name')},
callback: function() {
$(ele).parent().toggle(false);
}
});
},
show_active_users: function() {
var me = this;
wn.call({
module:'utilities',
page:'messages',
method:'get_active_users',
callback: function(r,rt) {
var $body = $(me.wrapper).find('.layout-side-section');
$('<h4>Users</h4><hr>\
<div id="show-everyone">\
<a href="#messages/'+user+'" class="btn">\
Show messages from everyone</a><hr></div>\
').appendTo($body);
r.message.sort(function(a, b) { return b.has_session - a.has_session; });
for(var i in r.message) {
var p = r.message[i];
if(p.name != user) {
p.fullname = wn.user_info(p.name).fullname;
p.image = wn.utils.get_file_link(wn.user_info(p.name).image);
p.name = p.name.replace('@', '__at__');
p.status_color = p.has_session ? "green" : "#ddd";
p.status = p.has_session ? "Online" : "Offline";
$(repl('<p>\
<span class="avatar avatar-small" \
style="border: 3px solid %(status_color)s" \
title="%(status)s"><img src="%(image)s"></span>\
<a href="#!messages/%(name)s">%(fullname)s</a>\
</p>', p))
.appendTo($body);
}
}
}
});
}
});

View File

@ -1,117 +0,0 @@
# ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
@webnotes.whitelist()
def get_list(arg=None):
"""get list of messages"""
webnotes.form_dict['limit_start'] = int(webnotes.form_dict['limit_start'])
webnotes.form_dict['limit_page_length'] = int(webnotes.form_dict['limit_page_length'])
webnotes.form_dict['user'] = webnotes.session['user']
# set all messages as read
webnotes.conn.begin()
webnotes.conn.sql("""UPDATE `tabComment`
set docstatus = 1 where comment_doctype in ('My Company', 'Message')
and comment_docname = %s
""", webnotes.user.name)
webnotes.conn.commit()
if webnotes.form_dict['contact'] == webnotes.session['user']:
# return messages
return webnotes.conn.sql("""select * from `tabComment`
where (owner=%(contact)s
or comment_docname=%(user)s
or (owner=comment_docname and ifnull(parenttype, "")!="Assignment"))
and comment_doctype ='Message'
order by creation desc
limit %(limit_start)s, %(limit_page_length)s""", webnotes.form_dict, as_dict=1)
else:
return webnotes.conn.sql("""select * from `tabComment`
where (owner=%(contact)s and comment_docname=%(user)s)
or (owner=%(user)s and comment_docname=%(contact)s)
or (owner=%(contact)s and comment_docname=%(contact)s)
and comment_doctype ='Message'
order by creation desc
limit %(limit_start)s, %(limit_page_length)s""", webnotes.form_dict, as_dict=1)
@webnotes.whitelist()
def get_active_users(arg=None):
return webnotes.conn.sql("""select name,
(select count(*) from tabSessions where user=tabProfile.name
and timediff(now(), lastupdate) < time("01:00:00")) as has_session
from tabProfile
where ifnull(enabled,0)=1 and
docstatus < 2 and
name not in ('Administrator', 'Guest')
order by first_name""", as_dict=1)
@webnotes.whitelist()
def post(arg=None):
import webnotes
"""post message"""
if not arg:
arg = {}
arg.update(webnotes.form_dict)
if isinstance(arg, basestring):
import json
arg = json.loads(arg)
from webnotes.model.doc import Document
d = Document('Comment')
d.parenttype = arg.get("parenttype")
d.comment = arg['txt']
d.comment_docname = arg['contact']
d.comment_doctype = 'Message'
d.save()
import webnotes.utils
if webnotes.utils.cint(arg.get('notify')):
notify(arg)
@webnotes.whitelist()
def delete(arg=None):
webnotes.conn.sql("""delete from `tabComment` where name=%s""",
webnotes.form_dict['name']);
def notify(arg=None):
from webnotes.utils import cstr, get_fullname
from startup import get_url
fn = get_fullname(webnotes.user.name) or webnotes.user.name
url = get_url()
message = '''You have a message from <b>%s</b>:
%s
To answer, please login to your erpnext account at \
<a href=\"%s\" target='_blank'>%s</a>
''' % (fn, arg['txt'], url, url)
sender = webnotes.conn.get_value("Profile", webnotes.user.name, "email") \
or webnotes.user.name
recipient = [webnotes.conn.get_value("Profile", arg["contact"], "email") \
or arg["contact"]]
from webnotes.utils.email_lib import sendmail
sendmail(recipient, sender, message, arg.get("subject") or "You have a message from %s" % (fn,))

View File

@ -1,21 +0,0 @@
[
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-02-24 11:21:57",
"modified_by": "Administrator",
"modified": "2012-02-24 11:21:57"
},
{
"name": "__common__",
"title": "Messages",
"module": "Utilities",
"doctype": "Page",
"page_name": "messages",
"standard": "Yes"
},
{
"name": "messages",
"doctype": "Page"
}
]

View File

@ -1 +0,0 @@
from __future__ import unicode_literals

View File

@ -1,51 +0,0 @@
.todoitem {
padding-bottom: 3px;
clear: both;
}
.todoitem div {
float: left;
display: inline-block;
padding: 3px;
}
.todoitem .label {
width: 50px;
margin-right: 11px;
margin-top: 3px;
text-align: center;
}
.todoitem .todo-date {
margin-top: -2px;
margin-right: 7px;
color: #aaa;
}
.todoitem .close {
margin-left: 5px;
font-size: 17px;
}
.todoitem .close-span {
float: right;
}
.todo-separator {
border-bottom: 1px solid #DEB85F;
margin-bottom: 5px;
clear: both;
}
.todo-content {
padding-right: 15px;
}
.todo-layout {
background-color: #FFFDC9;
min-height: 300px;
}
.todoitem .popup-on-click {
margin: 0px 6px;
}

View File

@ -1,11 +0,0 @@
<div class="layout-wrapper layout-wrapper-background">
<div class="appframe-area"></div>
<div class="layout-main todo-layout">
<div>
<div id="todo-list">
<div class="todo-content"></div>
</div>
</div>
<div style="clear: both"></div>
</div>
</div>

View File

@ -1,212 +0,0 @@
// ERPNext - web based ERP (http://erpnext.com)
// Copyright (C) 2012 Web Notes Technologies Pvt Ltd
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
wn.provide('erpnext.todo');
erpnext.todo.refresh = function() {
wn.call({
method: 'utilities.page.todo.todo.get',
callback: function(r,rt) {
var todo_list = $('#todo-list div.todo-content');
var assigned_todo_list = $('#assigned-todo-list div.todo-content');
todo_list.empty();
assigned_todo_list.empty();
var nothing_to_do = function() {
$('#todo-list div.todo-content')
.html('<div class="alert">Nothing to do :)</div>');
}
if(r.message) {
for(var i in r.message) {
new erpnext.todo.ToDoItem(r.message[i]);
}
if (!todo_list.html()) { nothing_to_do(); }
} else {
nothing_to_do();
}
}
});
}
erpnext.todo.ToDoItem = Class.extend({
init: function(todo) {
label_map = {
'High': 'label-important',
'Medium': 'label-info',
'Low':''
}
todo.labelclass = label_map[todo.priority];
todo.userdate = dateutil.str_to_user(todo.date) || '';
todo.fullname = '';
if(todo.assigned_by) {
var assigned_by = wn.boot.user_info[todo.assigned_by]
todo.fullname = repl("[By %(fullname)s] ".bold(), {
fullname: (assigned_by ? assigned_by.fullname : todo.assigned_by),
});
}
var parent_list = "#todo-list";
if(todo.owner !== user) {
var owner = wn.boot.user_info[todo.owner];
todo.fullname = repl("[To %(fullname)s] ".bold(), {
fullname: (owner ? owner.fullname : todo.owner),
});
}
parent_list += " div.todo-content";
if(todo.reference_name && todo.reference_type) {
todo.link = repl('<a href="#!Form/%(reference_type)s/%(reference_name)s">\
%(reference_type)s: %(reference_name)s</a>', todo);
} else if(todo.reference_type) {
todo.link = repl('<br><a href="#!List/%(reference_type)s">\
%(reference_type)s</a>', todo);
} else {
todo.link = '';
}
if(!todo.description) todo.description = '';
todo.description_display = todo.description.replace(/\n\n/g, "<br>").trim();
$(parent_list).append(repl('\
<div class="todoitem">\
<div class="label %(labelclass)s">%(priority)s</div>\
<div class="popup-on-click"><a href="#">[edit]</a></div>\
<div class="todo-date-fullname">\
<div class="todo-date">%(userdate)s</div>\
%(fullname)s:\
</div>\
<div class="description">%(description_display)s\
<span class="ref_link">%(link)s</span>\
</div>\
<div class="close-span"><a href="#" class="close">&times;</a></div>\
</div>\
<div class="todo-separator"></div>', todo));
$todo = $(parent_list + ' div.todoitem:last');
if(todo.checked) {
$todo.find('.description').css('text-decoration', 'line-through');
}
if(!todo.reference_type)
$todo.find('.ref_link').toggle(false);
$todo.find('.popup-on-click')
.data('todo', todo)
.click(function() {
erpnext.todo.make_dialog($(this).data('todo'));
return false;
});
$todo.find('.close')
.data('name', todo.name)
.click(function() {
$(this).parent().css('opacity', 0.5);
wn.call({
method:'utilities.page.todo.todo.delete',
args: {name: $(this).data('name')},
callback: function() {
erpnext.todo.refresh();
}
});
return false;
})
}
});
erpnext.todo.make_dialog = function(det) {
if(!erpnext.todo.dialog) {
var dialog = new wn.ui.Dialog({
width: 480,
title: 'To Do',
fields: [
{fieldtype:'Text', fieldname:'description', label:'Description',
reqd:1},
{fieldtype:'Date', fieldname:'date', label:'Event Date', reqd:1},
{fieldtype:'Check', fieldname:'checked', label:'Completed'},
{fieldtype:'Select', fieldname:'priority', label:'Priority', reqd:1, 'options':['Medium','High','Low'].join('\n')},
{fieldtype:'Button', fieldname:'save', label:'Save (Ctrl+S)'}
]
});
dialog.fields_dict.save.input.onclick = function() {
erpnext.todo.save(this);
}
erpnext.todo.dialog = dialog;
}
if(det) {
erpnext.todo.dialog.set_values({
date: det.date,
priority: det.priority,
description: det.description,
checked: det.checked
});
erpnext.todo.dialog.det = det;
}
erpnext.todo.dialog.show();
}
erpnext.todo.save = function(btn) {
var d = erpnext.todo.dialog;
var det = d.get_values();
if(!det) {
return;
}
det.name = d.det.name || '';
wn.call({
method:'utilities.page.todo.todo.edit',
args: det,
btn: btn,
callback: function() {
erpnext.todo.dialog.hide();
erpnext.todo.refresh();
}
});
}
wn.pages.todo.onload = function(wrapper) {
// create app frame
wrapper.appframe = new wn.ui.AppFrame($(wrapper).find('.appframe-area'), 'To Do');
wrapper.appframe.add_home_breadcrumb();
wrapper.appframe.add_breadcrumb(wn.modules["To Do"].icon);
wrapper.appframe.add_button('Refresh', erpnext.todo.refresh, 'icon-refresh');
wrapper.appframe.add_button('Add', function() {
erpnext.todo.make_dialog({
date:get_today(), priority:'Medium', checked:0, description:''});
}, 'icon-plus');
wrapper.appframe.add_ripped_paper_effect(wrapper);
// show report button for System Manager
if(wn.boot.profile.roles.indexOf("System Manager") !== -1) {
wrapper.appframe.add_button("Report", function() { wn.set_route("query-report", "todo"); },
"icon-table");
}
// load todos
erpnext.todo.refresh();
// save on click
wrapper.save_action = function() {
if(erpnext.todo.dialog && erpnext.todo.dialog.display) {
erpnext.todo.dialog.fields_dict.save.input.click();
}
};
}

View File

@ -1,64 +0,0 @@
# ERPNext - web based ERP (http://erpnext.com)
# Copyright (C) 2012 Web Notes Technologies Pvt Ltd
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
from __future__ import unicode_literals
import webnotes
from webnotes.model.doc import Document
@webnotes.whitelist()
def get(arg=None):
"""get todo list"""
return webnotes.conn.sql("""select name, owner, description, date,
priority, checked, reference_type, reference_name, assigned_by
from `tabToDo` where (owner=%s or assigned_by=%s)
order by field(priority, 'High', 'Medium', 'Low') asc, date asc""",
(webnotes.session['user'], webnotes.session['user']), as_dict=1)
@webnotes.whitelist()
def edit(arg=None):
import markdown2
args = webnotes.form_dict
d = Document('ToDo', args.get('name') or None)
d.description = args['description']
d.date = args['date']
d.priority = args['priority']
d.checked = args.get('checked', 0)
if not d.owner: d.owner = webnotes.session['user']
d.save(not args.get('name') and 1 or 0)
if args.get('name') and d.checked:
notify_assignment(d)
return d.name
@webnotes.whitelist()
def delete(arg=None):
name = webnotes.form_dict['name']
d = Document('ToDo', name)
if d and d.name and d.owner != webnotes.session['user']:
notify_assignment(d)
webnotes.conn.sql("delete from `tabToDo` where name = %s", name)
def notify_assignment(d):
doc_type = d.reference_type
doc_name = d.reference_name
assigned_by = d.assigned_by
if doc_type and doc_name and assigned_by:
from webnotes.widgets.form import assign_to
assign_to.notify_assignment(assigned_by, d.owner, doc_type, doc_name)

View File

@ -1,21 +0,0 @@
[
{
"owner": "Administrator",
"docstatus": 0,
"creation": "2012-02-23 13:59:03",
"modified_by": "Administrator",
"modified": "2012-02-23 13:59:03"
},
{
"name": "__common__",
"title": "To Do",
"module": "Utilities",
"doctype": "Page",
"page_name": "todo",
"standard": "Yes"
},
{
"name": "todo",
"doctype": "Page"
}
]