27 changed files with 1483 additions and 2 deletions
-
13apps/calendar/lib/app.php
-
26apps/tasks/ajax/addtask.php
-
20apps/tasks/ajax/addtaskform.php
-
31apps/tasks/ajax/delete.php
-
31apps/tasks/ajax/edittask.php
-
24apps/tasks/ajax/edittaskform.php
-
24apps/tasks/ajax/getdetails.php
-
36apps/tasks/ajax/gettasks.php
-
68apps/tasks/ajax/update_property.php
-
16apps/tasks/appinfo/app.php
-
10apps/tasks/appinfo/info.xml
-
59apps/tasks/css/style.css
-
BINapps/tasks/img/icon.png
-
101apps/tasks/img/icon.svg
-
34apps/tasks/index.php
-
532apps/tasks/js/tasks.js
-
187apps/tasks/lib/app.php
-
27apps/tasks/lib/vtodo.php
-
15apps/tasks/templates/part.addtaskform.php
-
42apps/tasks/templates/part.details.php
-
5apps/tasks/templates/part.edittaskform.php
-
22apps/tasks/templates/part.property.php
-
36apps/tasks/templates/part.taskform.php
-
3apps/tasks/templates/part.tasks.php
-
31apps/tasks/templates/tasks.php
-
BINcore/img/actions/triangle-n.png
-
92core/img/actions/triangle-n.svg
@ -0,0 +1,26 @@ |
|||
<?php |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); |
|||
$cid = reset($calendars)['id']; |
|||
|
|||
$input = $_GET['text']; |
|||
$request = array(); |
|||
$request['summary'] = $input; |
|||
$request["categories"] = null; |
|||
$request['priority'] = null; |
|||
$request['percent_complete'] = null; |
|||
$request['completed'] = null; |
|||
$request['location'] = null; |
|||
$request['due'] = null; |
|||
$request['description'] = null; |
|||
$vcalendar = OC_Task_App::createVCalendarFromRequest($request); |
|||
$id = OC_Calendar_Object::add($cid, $vcalendar->serialize()); |
|||
|
|||
$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
$task = OC_Task_App::arrayForJSON($id, $vcalendar->VTODO, $user_timezone); |
|||
|
|||
OCP\JSON::success(array('task' => $task)); |
|||
@ -0,0 +1,20 @@ |
|||
<?php |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); |
|||
$category_options = OC_Calendar_App::getCategoryOptions(); |
|||
$percent_options = range(0, 100, 10); |
|||
$priority_options = OC_Task_App::getPriorityOptions(); |
|||
$tmpl = new OC_Template('tasks','part.addtaskform'); |
|||
$tmpl->assign('calendars',$calendars); |
|||
$tmpl->assign('category_options', $category_options); |
|||
$tmpl->assign('percent_options', $percent_options); |
|||
$tmpl->assign('priority_options', $priority_options); |
|||
$tmpl->assign('details', new OC_VObject('VTODO')); |
|||
$tmpl->assign('categories', ''); |
|||
$page = $tmpl->fetchPage(); |
|||
|
|||
OCP\JSON::success(array('data' => array( 'page' => $page ))); |
|||
@ -0,0 +1,31 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud - Addressbook |
|||
* |
|||
* @author Jakob Sack |
|||
* @copyright 2011 Jakob Sack mail@jakobsack.de |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$id = $_GET['id']; |
|||
$task = OC_Calendar_App::getEventObject( $id ); |
|||
|
|||
OC_Calendar_Object::delete($id); |
|||
OCP\JSON::success(array('data' => array( 'id' => $id ))); |
|||
@ -0,0 +1,31 @@ |
|||
<?php |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$l10n = new OC_L10N('tasks'); |
|||
|
|||
$id = $_POST['id']; |
|||
$vcalendar = OC_Calendar_App::getVCalendar($id); |
|||
|
|||
$errors = OC_Task_App::validateRequest($_POST); |
|||
if (!empty($errors)) { |
|||
OCP\JSON::error(array('data' => array( 'errors' => $errors ))); |
|||
exit(); |
|||
} |
|||
|
|||
OC_Task_App::updateVCalendarFromRequest($_POST, $vcalendar); |
|||
OC_Calendar_Object::edit($id, $vcalendar->serialize()); |
|||
|
|||
$priority_options = OC_Task_App::getPriorityOptions(); |
|||
$tmpl = new OC_Template('tasks','part.details'); |
|||
$tmpl->assign('priority_options', $priority_options); |
|||
$tmpl->assign('details', $vcalendar->VTODO); |
|||
$tmpl->assign('id', $id); |
|||
$page = $tmpl->fetchPage(); |
|||
|
|||
$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
$task = OC_Task_App::arrayForJSON($id, $vcalendar->VTODO, $user_timezone); |
|||
|
|||
OCP\JSON::success(array('data' => array( 'id' => $id, 'page' => $page, 'task' => $task ))); |
|||
@ -0,0 +1,24 @@ |
|||
<?php |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$id = $_GET['id']; |
|||
$details = OC_Calendar_App::getVCalendar($id)->VTODO; |
|||
$categories = $details->getAsString('CATEGORIES'); |
|||
|
|||
$category_options = OC_Calendar_App::getCategoryOptions(); |
|||
$percent_options = range(0, 100, 10); |
|||
$priority_options = OC_Task_App::getPriorityOptions(); |
|||
|
|||
$tmpl = new OC_Template('tasks','part.edittaskform'); |
|||
$tmpl->assign('category_options', $category_options); |
|||
$tmpl->assign('percent_options', $percent_options); |
|||
$tmpl->assign('priority_options', $priority_options); |
|||
$tmpl->assign('id',$id); |
|||
$tmpl->assign('details',$details); |
|||
$tmpl->assign('categories', $categories); |
|||
$page = $tmpl->fetchPage(); |
|||
|
|||
OCP\JSON::success(array('data' => array( 'page' => $page ))); |
|||
@ -0,0 +1,24 @@ |
|||
<?php |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$l10n = new OC_L10N('tasks'); |
|||
|
|||
$id = $_GET['id']; |
|||
$task = OC_Calendar_Object::find($id); |
|||
$details = OC_VObject::parse($task['calendardata']); |
|||
if (!$details){ |
|||
OCP\JSON::error(); |
|||
exit; |
|||
} |
|||
|
|||
$priority_options = OC_Task_App::getPriorityOptions(); |
|||
$tmpl = new OC_Template('tasks','part.details'); |
|||
$tmpl->assign('priority_options', $priority_options); |
|||
$tmpl->assign('details',$details->VTODO); |
|||
$tmpl->assign('id',$id); |
|||
$page = $tmpl->fetchPage(); |
|||
|
|||
OCP\JSON::success(array('data' => array( 'id' => $id, 'page' => $page ))); |
|||
@ -0,0 +1,36 @@ |
|||
<?php |
|||
/** |
|||
* Copyright (c) 2011 Georg Ehrke <ownclouddev at georgswebsite dot de> |
|||
* This file is licensed under the Affero General Public License version 3 or |
|||
* later. |
|||
* See the COPYING-README file. |
|||
*/ |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); |
|||
$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
|
|||
$tasks = array(); |
|||
foreach( $calendars as $calendar ){ |
|||
$calendar_tasks = OC_Calendar_Object::all($calendar['id']); |
|||
foreach( $calendar_tasks as $task ){ |
|||
if($task['objecttype']!='VTODO'){ |
|||
continue; |
|||
} |
|||
if(is_null($task['summary'])){ |
|||
continue; |
|||
} |
|||
$object = OC_VObject::parse($task['calendardata']); |
|||
$vtodo = $object->VTODO; |
|||
try { |
|||
$tasks[] = OC_Task_App::arrayForJSON($task['id'], $vtodo, $user_timezone); |
|||
} catch(Exception $e) { |
|||
OCP\Util::writeLog('tasks', $e->getMessage(), OCP\Util::ERROR); |
|||
} |
|||
} |
|||
} |
|||
|
|||
OCP\JSON::encodedPrint($tasks); |
|||
@ -0,0 +1,68 @@ |
|||
<?php |
|||
/** |
|||
* Copyright (c) 2012 Bart Visscher <bartv@thisnet.nl> |
|||
* This file is licensed under the Affero General Public License version 3 or |
|||
* later. |
|||
* See the COPYING-README file. |
|||
*/ |
|||
|
|||
// Init owncloud
|
|||
OCP\JSON::checkLoggedIn(); |
|||
OCP\JSON::checkAppEnabled('tasks'); |
|||
|
|||
$id = $_POST['id']; |
|||
$property = $_POST['type']; |
|||
$vcalendar = OC_Calendar_App::getVCalendar( $id ); |
|||
|
|||
$vtodo = $vcalendar->VTODO; |
|||
switch($property) { |
|||
case 'summary': |
|||
$summary = $_POST['summary']; |
|||
$vtodo->setString('SUMMARY', $summary); |
|||
break; |
|||
case 'description': |
|||
$description = $_POST['description']; |
|||
$vtodo->setString('DESCRIPTION', $description); |
|||
break; |
|||
case 'location': |
|||
$location = $_POST['location']; |
|||
$vtodo->setString('LOCATION', $location); |
|||
break; |
|||
case 'categories': |
|||
$categories = $_POST['categories']; |
|||
$vtodo->setString('CATEGORIES', $categories); |
|||
break; |
|||
case 'due': |
|||
$due = $_POST['due']; |
|||
$due_date_only = $_POST['date']; |
|||
$type = null; |
|||
if ($due != 'false') { |
|||
try { |
|||
$timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
$timezone = new DateTimeZone($timezone); |
|||
$due = new DateTime('@'.$due); |
|||
$due->setTimezone($timezone); |
|||
$type = Sabre_VObject_Element_DateTime::LOCALTZ; |
|||
if ($due_date_only) { |
|||
$type = Sabre_VObject_Element_DateTime::DATE; |
|||
} |
|||
} catch (Exception $e) { |
|||
OCP\JSON::error(array('data'=>array('message'=>OC_Task_App::$l10n->t('Invalid date/time')))); |
|||
exit(); |
|||
} |
|||
} |
|||
$vtodo->setDateTime('DUE', $due, $type); |
|||
break; |
|||
case 'complete': |
|||
$checked = $_POST['checked']; |
|||
OC_Task_App::setComplete($vtodo, $checked ? '100' : '0', null); |
|||
break; |
|||
default: |
|||
OCP\JSON::error(array('data'=>array('message'=>'Unknown type'))); |
|||
exit(); |
|||
} |
|||
OC_Calendar_Object::edit($id, $vcalendar->serialize()); |
|||
|
|||
$user_timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
$task_info = OC_Task_App::arrayForJSON($id, $vtodo, $user_timezone); |
|||
OCP\JSON::success(array('data' => $task_info)); |
|||
@ -0,0 +1,16 @@ |
|||
<?php |
|||
$l=new OC_L10N('tasks'); |
|||
OC::$CLASSPATH['OC_Calendar_Calendar'] = 'apps/calendar/lib/calendar.php'; |
|||
OC::$CLASSPATH['OC_Task_App'] = 'apps/tasks/lib/app.php'; |
|||
|
|||
OCP\App::register( array( |
|||
'order' => 11, |
|||
'id' => 'tasks', |
|||
'name' => 'Tasks' )); |
|||
|
|||
OCP\App::addNavigationEntry( array( |
|||
'id' => 'tasks_index', |
|||
'order' => 11, |
|||
'href' => OCP\Util::linkTo( 'tasks', 'index.php' ), |
|||
'icon' => OCP\Util::imagePath( 'tasks', 'icon.png' ), |
|||
'name' => $l->t('Tasks'))); |
|||
@ -0,0 +1,10 @@ |
|||
<?xml version="1.0"?> |
|||
<info> |
|||
<id>tasks</id> |
|||
<name>Tasks</name> |
|||
<version>0.1</version> |
|||
<licence>AGPL</licence> |
|||
<author>Bart Visscher</author> |
|||
<require>2</require> |
|||
<description>Tasks view from calendar</description> |
|||
</info> |
|||
@ -0,0 +1,59 @@ |
|||
#tasks_list p.loading{margin:15px;} |
|||
#tasks_lists .done{color:#C7C7C7;} |
|||
#task_details{position:absolute;left:63em;top:6.4em;} |
|||
#task_details th{padding:2px;text-align:right;vertical-align:top; } |
|||
#task_details td{padding:2px;text-align:left;vertical-align:top; } |
|||
.error_msg{color:red;} |
|||
.error{border-color:red;border-width:2px;} |
|||
#tasks_lists div{position:relative;padding:0.5em 1em;} |
|||
#tasks_lists .active{font-weight:bold;} |
|||
#tasks_list h1{background-color:#1D2D44;color:white;font-size:120%;padding:0 0.5em;} |
|||
|
|||
.task{border-radius:0.4em;position:relative;padding:0.5em 1em;} |
|||
.task:nth-child(odd){background-color:#F4F4F4;} |
|||
.task:hover {background-color:#DDDDDD;} |
|||
|
|||
.task_actions{display:none;position:absolute;left:30em;top:0.2em;} |
|||
.task:hover .task_actions {display:block} |
|||
.task_actions img{vertical-align:middle;} |
|||
.task_actions span{cursor:pointer;} |
|||
|
|||
.task .priority{background-color:black;color:white;position:absolute;top:0.5em} |
|||
.task .priority-n{height:2.66ex;width:0.6em;} |
|||
.task .priority-1{background:rgb(255,0,0);} |
|||
.task .priority-2{background:rgb(200,0,0);} |
|||
.task .priority-3{background:rgb(150,0,0);} |
|||
.task .priority-4{background:rgb(100,0,0);} |
|||
.task .priority-5{background:rgb(255,255,0);color:black;} |
|||
.task .priority-6{background:rgb(192,255,0);color:black;} |
|||
.task .priority-7{background:rgb(128,255,0);color:black;} |
|||
.task .priority-8{background:rgb(64,255,0);color:black;} |
|||
.task .priority-9{background:rgb(0,255,0);color:black;} |
|||
|
|||
.task .completed {position:absolute;left:3em;top:0.3em;} |
|||
|
|||
.task .summary{padding-left:4em;} |
|||
.task .summary input{position:relative;left:5px;} |
|||
.task.done .summary{text-decoration:line-through;} |
|||
|
|||
.task .tag{border-radius:0.4em;display:inline-block;opacity:0.2;margin:0 0.2em;border:1px solid transparent;padding:0 0.4em;cursor:pointer;} |
|||
.task .tag.active{border-color:black;opacity:0.6;} |
|||
.task .tag.active:hover{opacity:1;} |
|||
.task:hover .tag{opacity:0.5} |
|||
.task:hover .tag:hover{opacity:0.8;} |
|||
|
|||
.task .categories{position:absolute;right:12em;text-align:right;top:0.4em} |
|||
.task .categories a{background-color:#1d2d44;color:white;} |
|||
.task .categories .tag.active{display:none;} |
|||
.task input.categories{display:none;top:0;text-align:left;} |
|||
|
|||
.task .location{background-color:#442d44;color:white;position:absolute;right:0.6em;width:9.2em;text-align:left;top:0.4em} |
|||
.task input.location{display:none;top:0;text-align:left;right:0.3em;background-color:white;color:#333333;} |
|||
|
|||
.task .more{display:none;margin-top:0.5em;} |
|||
.task_less{display:none;} |
|||
|
|||
.task .description{position:relative;left:4em;} |
|||
.task .due{position:absolute;right:0.3em;} |
|||
.task .due .date{width:6em;} |
|||
.task .due .time{width:6em;} |
|||
|
After Width: 16 | Height: 16 | Size: 457 B |
@ -0,0 +1,101 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
|||
<!-- Created with Inkscape (http://www.inkscape.org/) --> |
|||
|
|||
<svg |
|||
xmlns:dc="http://purl.org/dc/elements/1.1/" |
|||
xmlns:cc="http://creativecommons.org/ns#" |
|||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|||
xmlns:svg="http://www.w3.org/2000/svg" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
|||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
|||
width="16" |
|||
height="16" |
|||
id="svg2" |
|||
version="1.1" |
|||
inkscape:version="0.48.2 r9819" |
|||
sodipodi:docname="New document 1"> |
|||
<defs |
|||
id="defs4"> |
|||
<marker |
|||
style="overflow:visible" |
|||
inkscape:stockid="InfiniteLineStart" |
|||
id="InfiniteLineStart" |
|||
refX="0" |
|||
refY="0" |
|||
orient="auto"> |
|||
<g |
|||
id="g4011" |
|||
transform="translate(-13,0)"> |
|||
<circle |
|||
d="M 3.8,0 C 3.8,0.44182781 3.4418278,0.80000001 3,0.80000001 2.5581722,0.80000001 2.2,0.44182781 2.2,0 c 0,-0.44182781 0.3581722,-0.80000001 0.8,-0.80000001 0.4418278,0 0.8,0.3581722 0.8,0.80000001 z" |
|||
id="circle4013" |
|||
r="0.8" |
|||
cy="0" |
|||
cx="3" /> |
|||
<circle |
|||
d="M 7.3,0 C 7.3,0.44182781 6.9418278,0.80000001 6.5,0.80000001 6.0581722,0.80000001 5.7,0.44182781 5.7,0 c 0,-0.44182781 0.3581722,-0.80000001 0.8,-0.80000001 0.4418278,0 0.8,0.3581722 0.8,0.80000001 z" |
|||
id="circle4015" |
|||
r="0.8" |
|||
cy="0" |
|||
cx="6.5" /> |
|||
<circle |
|||
d="M 10.8,0 C 10.8,0.44182781 10.441828,0.80000001 10,0.80000001 9.5581722,0.80000001 9.2,0.44182781 9.2,0 c 0,-0.44182781 0.3581722,-0.80000001 0.8,-0.80000001 0.441828,0 0.8,0.3581722 0.8,0.80000001 z" |
|||
id="circle4017" |
|||
r="0.8" |
|||
cy="0" |
|||
cx="10" /> |
|||
</g> |
|||
</marker> |
|||
</defs> |
|||
<sodipodi:namedview |
|||
id="base" |
|||
pagecolor="#ffffff" |
|||
bordercolor="#666666" |
|||
borderopacity="1.0" |
|||
inkscape:pageopacity="0.0" |
|||
inkscape:pageshadow="2" |
|||
inkscape:zoom="1" |
|||
inkscape:cx="21.051806" |
|||
inkscape:cy="18.371489" |
|||
inkscape:document-units="px" |
|||
inkscape:current-layer="layer1" |
|||
showgrid="false" |
|||
showborder="false" |
|||
inkscape:showpageshadow="true" |
|||
inkscape:window-width="1280" |
|||
inkscape:window-height="1004" |
|||
inkscape:window-x="1278" |
|||
inkscape:window-y="-3" |
|||
inkscape:window-maximized="1" /> |
|||
<metadata |
|||
id="metadata7"> |
|||
<rdf:RDF> |
|||
<cc:Work |
|||
rdf:about=""> |
|||
<dc:format>image/svg+xml</dc:format> |
|||
<dc:type |
|||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
|||
<dc:title></dc:title> |
|||
</cc:Work> |
|||
</rdf:RDF> |
|||
</metadata> |
|||
<g |
|||
inkscape:label="Layer 1" |
|||
inkscape:groupmode="layer" |
|||
id="layer1" |
|||
transform="translate(0,-1036.3622)"> |
|||
<rect |
|||
style="fill:none;stroke:#000000;stroke-width:1.00000012;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none" |
|||
id="rect4398" |
|||
width="9" |
|||
height="9" |
|||
x="3.4999998" |
|||
y="1040.8619" /> |
|||
<path |
|||
style="fill:none;stroke:#808080;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;marker-start:none" |
|||
d="m 3.971,1040.0481 c 3.3062306,2.8933 3.3751101,6.5431 3.3751101,6.5431 0,0 3.8228259,-5.3027 6.2336249,-6.3371" |
|||
inkscape:connector-curvature="0" |
|||
sodipodi:nodetypes="ccc" /> |
|||
</g> |
|||
</svg> |
|||
@ -0,0 +1,34 @@ |
|||
<?php |
|||
/************************************************* |
|||
* ownCloud - Tasks Plugin * |
|||
* * |
|||
* (c) Copyright 2011 Bart Visscher * |
|||
* This file is licensed under the Affero General * |
|||
* Public License version 3 or later. * |
|||
* See the COPYING-README file. * |
|||
*************************************************/ |
|||
|
|||
OCP\User::checkLoggedIn(); |
|||
OCP\App::checkAppEnabled('tasks'); |
|||
|
|||
$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser(), true); |
|||
if( count($calendars) == 0 ) { |
|||
header('Location: ' . OCP\Util::linkTo('calendar', 'index.php')); |
|||
exit; |
|||
} |
|||
|
|||
OCP\Util::addScript('3rdparty/timepicker', 'jquery.ui.timepicker'); |
|||
OCP\Util::addStyle('3rdparty/timepicker', 'jquery.ui.timepicker'); |
|||
OCP\Util::addScript('tasks', 'tasks'); |
|||
OCP\Util::addStyle('tasks', 'style'); |
|||
OCP\Util::addScript('contacts','jquery.multi-autocomplete'); |
|||
OCP\Util::addScript('','oc-vcategories'); |
|||
OCP\App::setActiveNavigationEntry('tasks_index'); |
|||
|
|||
$categories = OC_Calendar_App::getCategoryOptions(); |
|||
$l10n = new OC_L10N('tasks'); |
|||
$priority_options = OC_Task_App::getPriorityOptions(); |
|||
$output = new OC_Template('tasks', 'tasks', 'user'); |
|||
$output->assign('priority_options', $priority_options); |
|||
$output->assign('categories', $categories); |
|||
$output -> printPage(); |
|||
@ -0,0 +1,532 @@ |
|||
OC.Tasks = { |
|||
bool_string_cmp:function(a, b) { |
|||
if (a === b) { |
|||
return 0; |
|||
} |
|||
if (a === false) { |
|||
return -1; |
|||
} |
|||
if (b === false) { |
|||
return 1; |
|||
} |
|||
return a.localeCompare(b); |
|||
}, |
|||
create_task_div:function(task) { |
|||
var actions = $('#task_actions_template'); |
|||
var summary_container = $('<p class="summary">') |
|||
.attr('title', task.description) |
|||
; |
|||
OC.Tasks.setSummary(summary_container, task); |
|||
var task_container = $('<div>') |
|||
.addClass('task') |
|||
.data('task', task) |
|||
.data('show_count', 0) |
|||
.attr('data-id', task.id) |
|||
.append(summary_container) |
|||
.append(actions.clone().removeAttr('id')) |
|||
; |
|||
task_container.find('.summary a').click(OC.Tasks.summaryClickHandler); |
|||
var checkbox = $('<input type="checkbox">') |
|||
.click(OC.Tasks.complete_task); |
|||
if (task.completed) { |
|||
checkbox.attr('checked', 'checked'); |
|||
task_container.addClass('done'); |
|||
} |
|||
$('<div>') |
|||
.addClass('completed') |
|||
.append(checkbox) |
|||
.prependTo(task_container); |
|||
var priority = task.priority; |
|||
$('<div>') |
|||
.addClass('tag') |
|||
.addClass('priority') |
|||
.addClass('priority-'+(priority?priority:'n')) |
|||
.text(priority) |
|||
.prependTo(task_container); |
|||
if (task.location) { |
|||
$('<div>') |
|||
.addClass('tag') |
|||
.addClass('location') |
|||
.text(task.location) |
|||
.appendTo(task_container); |
|||
} |
|||
var $categories = $('<div>') |
|||
.addClass('categories') |
|||
.appendTo(task_container); |
|||
$(task.categories).each(function(i, category){ |
|||
$categories.append($('<a>') |
|||
.addClass('tag') |
|||
.text(category) |
|||
); |
|||
}); |
|||
task_container.find('.task_more').click(OC.Tasks.moreClickHandler); |
|||
task_container.find('.task_less').click(OC.Tasks.lessClickHandler); |
|||
var description = $('<textarea>') |
|||
.addClass('description') |
|||
.blur(function(){ |
|||
var task = $(this).closest('.task').data('task'); |
|||
var description = $(this).val(); |
|||
$.post(OC.filePath('tasks', 'ajax', 'update_property.php'), {id:task.id, type:'description', description:description}, function(jsondata){ |
|||
if(jsondata.status == 'success') { |
|||
task.description = description; |
|||
} |
|||
}); |
|||
}) |
|||
.text(task.description); |
|||
var due = $('<span>') |
|||
.addClass('due') |
|||
.append(t('tasks', 'Due')); |
|||
due |
|||
.append($('<input type="date">') |
|||
.addClass('date') |
|||
.datepicker({ |
|||
dateFormat: 'dd-mm-yy', |
|||
onClose: OC.Tasks.dueUpdateHandler |
|||
}), |
|||
$('<input type="time">') |
|||
.addClass('time') |
|||
.timepicker({ |
|||
showPeriodLabels:false, |
|||
onClose: OC.Tasks.dueUpdateHandler |
|||
}) |
|||
); |
|||
if (task.due){ |
|||
var date = new Date(parseInt(task.due)*1000); |
|||
due.find('.date').datepicker('setDate', date); |
|||
if (!task.due_date_only) { |
|||
due.find('.time').timepicker('setTime', date.getHours()+':'+date.getMinutes()); |
|||
} |
|||
} |
|||
$('<div>') |
|||
.addClass('more') |
|||
.append(description) |
|||
.append(due) |
|||
.appendTo(task_container); |
|||
$('<input placeholder="'+t('tasks', 'List')+'">') |
|||
.addClass('categories') |
|||
.multiple_autocomplete({source: categories}) |
|||
.val(task.categories) |
|||
.blur(function(){ |
|||
var task = $(this).closest('.task').data('task'); |
|||
var categories = $(this).val(); |
|||
$.post(OC.filePath('tasks', 'ajax', 'update_property.php'), {id:task.id, type:'categories', categories:categories}, function(jsondata){ |
|||
if(jsondata.status == 'success') { |
|||
task.categories = categories.split(','); |
|||
$categories.empty(); |
|||
$(task.categories).each(function(i, category){ |
|||
$categories.append($('<a>') |
|||
.addClass('tag') |
|||
.text(category) |
|||
); |
|||
}); |
|||
} |
|||
}); |
|||
}) |
|||
.appendTo(task_container); |
|||
$('<input placeholder="'+t('tasks', 'Location')+'">') |
|||
.addClass('location') |
|||
.val(task.location) |
|||
.blur(function(){ |
|||
var task = $(this).closest('.task').data('task'); |
|||
var location = $(this).val(); |
|||
$.post(OC.filePath('tasks', 'ajax', 'update_property.php'), {id:task.id, type:'location', location:location}, function(jsondata){ |
|||
if(jsondata.status == 'success') { |
|||
task.location = location; |
|||
task_container.find('.location').text(location); |
|||
} |
|||
}); |
|||
}) |
|||
.appendTo(task_container); |
|||
return task_container; |
|||
}, |
|||
filter:function(tag, find_filter) { |
|||
var tag_text = $(tag).text(); |
|||
var filter = !$(tag).hasClass('active'); |
|||
OC.Tasks.filterUpdate(filter, function(task_container){ |
|||
var found = 0; |
|||
task_container.find(find_filter).each(function(){ |
|||
if ($(this).text() == tag_text) { |
|||
$(this).toggleClass('active'); |
|||
found = 1; |
|||
} |
|||
}); |
|||
return found; |
|||
}); |
|||
}, |
|||
filterUpdate:function(filter, find_filter) { |
|||
var show_count = $('#tasks_list').data('show_count'); |
|||
show_count += filter ? +1 : -1; |
|||
$('#tasks_list').data('show_count', show_count); |
|||
$('#tasks_lists .task, #tasks_list .task').each(function(i, task_container){ |
|||
task_container = $(task_container); |
|||
var task = task_container.data('task'); |
|||
var found = find_filter(task_container); |
|||
var hide_count = task_container.data('show_count'); |
|||
if (!filter) { |
|||
hide_count-=found; |
|||
} |
|||
else { |
|||
hide_count+=found; |
|||
} |
|||
if (hide_count == show_count) { |
|||
task_container.show(); |
|||
} |
|||
else { |
|||
task_container.hide(); |
|||
} |
|||
task_container.data('show_count', hide_count); |
|||
}); |
|||
}, |
|||
order:function(sort, get_property, empty_label) { |
|||
var tasks = $('#tasks_list .task').not('.clone'); |
|||
tasks.sort(sort); |
|||
var current = null; |
|||
tasks.detach(); |
|||
var $tasks = $('#tasks_list').empty(); |
|||
var container = $tasks; |
|||
tasks.each(function(){ |
|||
if (get_property) { |
|||
var label = get_property($(this).data('task')); |
|||
if(label != current) { |
|||
current = label; |
|||
container = $('<div>').appendTo($tasks); |
|||
if (label == '' && empty_label) { |
|||
label = empty_label; |
|||
} |
|||
$('<h1>').text(label).appendTo(container); |
|||
} |
|||
} |
|||
container.append(this); |
|||
}); |
|||
}, |
|||
setSummary:function(summary_container, task){ |
|||
var summary = $('<a href="index.php?id='+task.id+'">') |
|||
.text(task.summary) |
|||
.click(OC.Tasks.summaryClickHandler); |
|||
summary_container.html(summary); |
|||
}, |
|||
summaryClickHandler:function(event){ |
|||
event.preventDefault(); |
|||
//event.stopPropagation();
|
|||
var task = $(this).closest('.task').data('task'); |
|||
var summary_container = $(this).parent(); |
|||
var input = $('<input>').val($(this).text()).blur(function(){ |
|||
var old_summary = task.summary; |
|||
task.summary = $(this).val(); |
|||
OC.Tasks.setSummary(summary_container, task); |
|||
$.post(OC.filePath('tasks', 'ajax', 'update_property.php'), {id:task.id, type:'summary', summary:task.summary}, function(jsondata){ |
|||
if(jsondata.status != 'success') { |
|||
task.summary = old_summary; |
|||
OC.Tasks.setSummary(summary_container, task); |
|||
} |
|||
}); |
|||
}); |
|||
summary_container.empty().append(input); |
|||
input.focus(); |
|||
return false; |
|||
}, |
|||
dueUpdateHandler:function(){ |
|||
var task = $(this).closest('.task').data('task'); |
|||
var old_due = task.due; |
|||
var $date = $(this).parent().children('.date'); |
|||
var $time = $(this).parent().children('.time'); |
|||
var date = $date.datepicker('getDate'); |
|||
var time = $time.val().split(':'); |
|||
var due, date_only = false; |
|||
if (!date){ |
|||
due = false; |
|||
} else { |
|||
if (time.length==2){ |
|||
date.setHours(time[0]); |
|||
date.setMinutes(time[1]); |
|||
} |
|||
else { |
|||
date_only = true; |
|||
} |
|||
due = date.getTime()/1000; |
|||
} |
|||
$.post(OC.filePath('tasks', 'ajax', 'update_property.php'), {id:task.id, type:'due', due:due, date:date_only?1:0}, function(jsondata){ |
|||
if(jsondata.status != 'success') { |
|||
task.due = old_due; |
|||
} |
|||
}); |
|||
}, |
|||
moreClickHandler:function(event){ |
|||
var $task = $(this).closest('.task'), |
|||
task = $task.data('task'); |
|||
$task.find('.more').show(); |
|||
$task.find('.task_more').hide(); |
|||
$task.find('.task_less').show(); |
|||
$task.find('div.categories').hide(); |
|||
$task.find('input.categories').show(); |
|||
$task.find('div.location').hide(); |
|||
$task.find('input.location').show(); |
|||
}, |
|||
lessClickHandler:function(event){ |
|||
var $task = $(this).closest('.task'), |
|||
task = $task.data('task'); |
|||
$task.find('.more').hide(); |
|||
$task.find('.task_more').show(); |
|||
$task.find('.task_less').hide(); |
|||
$task.find('div.categories').show(); |
|||
$task.find('input.categories').hide(); |
|||
$task.find('div.location').show(); |
|||
$task.find('input.location').hide(); |
|||
}, |
|||
complete_task:function() { |
|||
var $task = $(this).closest('.task'), |
|||
task = $task.data('task'), |
|||
checked = $(this).is(':checked'); |
|||
$.post(OC.filePath('tasks', 'ajax', 'update_property.php'), {id:task.id, type:'complete', checked:checked?1:0}, function(jsondata){ |
|||
if(jsondata.status == 'success') { |
|||
task = jsondata.data; |
|||
$task.data('task', task) |
|||
if (task.completed) { |
|||
$task.addClass('done'); |
|||
} |
|||
else { |
|||
$task.removeClass('done'); |
|||
} |
|||
} |
|||
else{ |
|||
alert(jsondata.data.message); |
|||
} |
|||
}, 'json'); |
|||
}, |
|||
categoriesChanged:function(newcategories){ |
|||
categories = $.map(newcategories, function(v) {return v;}); |
|||
console.log('Task categories changed to: ' + categories); |
|||
$('input.categories').multiple_autocomplete('option', 'source', categories); |
|||
}, |
|||
List: { |
|||
create_list_div:function(category){ |
|||
return $('<div>').text(category) |
|||
.click(function(){ |
|||
OC.Tasks.filter(this, 'div.categories .tag'); |
|||
$(this).toggleClass('active'); |
|||
}); |
|||
} |
|||
} |
|||
}; |
|||
|
|||
$(document).ready(function(){ |
|||
fillHeight($('#tasks_lists')); |
|||
fillWindow($('#tasks_list')); |
|||
|
|||
/*------------------------------------------------------------------------- |
|||
* Actions for startup |
|||
*-----------------------------------------------------------------------*/ |
|||
$.getJSON(OC.filePath('tasks', 'ajax', 'gettasks.php'), function(jsondata) { |
|||
var tasks = $('#tasks_list').empty().data('show_count', 0); |
|||
$(jsondata).each(function(i, task) { |
|||
tasks.append(OC.Tasks.create_task_div(task)); |
|||
}); |
|||
if( $('#tasks_list div').length > 0 ){ |
|||
$('#tasks_list div').first().addClass('active'); |
|||
} |
|||
$(categories).each(function(i, category) { |
|||
$('#tasks_lists .all').after(OC.Tasks.List.create_list_div(category)); |
|||
}); |
|||
$('#tasks_lists .all').click(function(){ |
|||
$('#tasks_lists .active').click(); |
|||
}); |
|||
$('#tasks_lists .done').click(function(){ |
|||
var filter = !$(this).hasClass('active'); |
|||
OC.Tasks.filterUpdate(filter, function(task_container){ |
|||
return task_container.hasClass('done'); |
|||
}); |
|||
$(this).toggleClass('active'); |
|||
}); |
|||
OCCategories.changed = OC.Tasks.categoriesChanged; |
|||
OCCategories.app = 'calendar'; |
|||
}); |
|||
|
|||
/*------------------------------------------------------------------------- |
|||
* Event handlers |
|||
*-----------------------------------------------------------------------*/ |
|||
$('#tasks_list div.categories .tag').live('click',function(){ |
|||
OC.Tasks.filter(this, 'div.categories .tag'); |
|||
var tag_text = $(this).text(); |
|||
$('#tasks_lists div:not(".all"):not(".done")').each(function(){ |
|||
if ($(this).text() == tag_text) { |
|||
$(this).toggleClass('active'); |
|||
} |
|||
}); |
|||
}); |
|||
|
|||
$('#tasks_list .priority.tag').live('click',function(){ |
|||
OC.Tasks.filter(this, '.priority.tag'); |
|||
}); |
|||
|
|||
$('#tasks_list .location.tag').live('click',function(){ |
|||
OC.Tasks.filter(this, '.location.tag'); |
|||
}); |
|||
|
|||
$('#tasks_order_category').click(function(){ |
|||
var tasks = $('#tasks_list .task').not('.clone'); |
|||
var collection = {}; |
|||
tasks.each(function(i, task) { |
|||
var categories = $(task).data('task').categories; |
|||
$(categories).each(function() { |
|||
if (!collection.hasOwnProperty(this)) { |
|||
collection[this] = []; |
|||
} |
|||
collection[this].push(task); |
|||
if (categories.length > 1) { |
|||
task = $(task).clone(true).addClass('clone').get(0); |
|||
} |
|||
}); |
|||
if (categories.length == 0) { |
|||
if (!collection.hasOwnProperty('')) { |
|||
collection[''] = []; |
|||
} |
|||
collection[''].push(task); |
|||
} |
|||
}); |
|||
var labels = []; |
|||
for (var label in collection) { |
|||
labels.push(label); |
|||
} |
|||
labels.sort(); |
|||
tasks.detach(); |
|||
var $tasks = $('#tasks_list').empty(); |
|||
for (var index in labels) { |
|||
var label = labels[index]; |
|||
var container = $('<div>').appendTo($tasks); |
|||
if (label == '') { |
|||
label = t('tasks', 'No category'); |
|||
} |
|||
$('<h1>').text(label).appendTo(container); |
|||
container.append(collection[labels[index]]); |
|||
} |
|||
}); |
|||
|
|||
$('#tasks_order_due').click(function(){ |
|||
OC.Tasks.order(function(a, b){ |
|||
a = $(a).data('task').due; |
|||
b = $(b).data('task').due; |
|||
return OC.Tasks.bool_string_cmp(a, b); |
|||
}); |
|||
}); |
|||
|
|||
$('#tasks_order_complete').click(function(){ |
|||
OC.Tasks.order(function(a, b){ |
|||
return ($(a).data('task').complete - $(b).data('task').complete) || |
|||
OC.Tasks.bool_string_cmp($(a).data('task').completed, $(b).data('task').completed); |
|||
}); |
|||
}); |
|||
|
|||
$('#tasks_order_location').click(function(){ |
|||
OC.Tasks.order(function(a, b){ |
|||
a = $(a).data('task').location; |
|||
b = $(b).data('task').location; |
|||
return OC.Tasks.bool_string_cmp(a, b); |
|||
}); |
|||
}); |
|||
|
|||
$('#tasks_order_prio').click(function(){ |
|||
OC.Tasks.order(function(a, b){ |
|||
return $(a).data('task').priority |
|||
- $(b).data('task').priority; |
|||
}); |
|||
}); |
|||
|
|||
$('#tasks_order_label').click(function(){ |
|||
OC.Tasks.order(function(a, b){ |
|||
return $(a).data('task').summary.localeCompare( |
|||
$(b).data('task').summary); |
|||
}); |
|||
}); |
|||
|
|||
$('#tasks_delete').live('click',function(){ |
|||
var id = $('#task_details').data('id'); |
|||
$.getJSON('ajax/delete.php',{'id':id},function(jsondata){ |
|||
if(jsondata.status == 'success'){ |
|||
$('#tasks [data-id="'+jsondata.data.id+'"]').remove(); |
|||
$('#task_details').data('id',''); |
|||
$('#task_details').html(''); |
|||
} |
|||
else{ |
|||
alert(jsondata.data.message); |
|||
} |
|||
}); |
|||
return false; |
|||
}); |
|||
|
|||
$('#tasks_addtask').click(function(){ |
|||
var input = $('#tasks_newtask').val(); |
|||
$.getJSON(OC.filePath('tasks', 'ajax', 'addtask.php'),{text:input},function(jsondata){ |
|||
if(jsondata.status == 'success'){ |
|||
$('#tasks_list').append(OC.Tasks.create_task_div(jsondata.task)); |
|||
} |
|||
else{ |
|||
alert(jsondata.data.message); |
|||
} |
|||
}); |
|||
return false; |
|||
}); |
|||
|
|||
$('#tasks_addtaskform input[type="submit"]').live('click',function(){ |
|||
$.post('ajax/addtask.php',$('#tasks_addtaskform').serialize(),function(jsondata){ |
|||
if(jsondata.status == 'success'){ |
|||
$('#task_details').data('id',jsondata.data.id); |
|||
$('#task_details').html(jsondata.data.page); |
|||
$('#tasks_list').append(OC.Tasks.create_task_div(jsondata.data.task)); |
|||
} |
|||
else{ |
|||
alert(jsondata.data.message); |
|||
} |
|||
}, 'json'); |
|||
return false; |
|||
}); |
|||
|
|||
$('#tasks_edit').live('click',function(){ |
|||
var id = $('#task_details').data('id'); |
|||
$.getJSON('ajax/edittaskform.php',{'id':id},function(jsondata){ |
|||
if(jsondata.status == 'success'){ |
|||
$('#task_details').html(jsondata.data.page); |
|||
$('#task_details #categories').multiple_autocomplete({source: categories}); |
|||
} |
|||
else{ |
|||
alert(jsondata.data.message); |
|||
} |
|||
}); |
|||
return false; |
|||
}); |
|||
|
|||
$('#tasks_edittaskform #percent_complete').live('change',function(event){ |
|||
if ($(event.target).val() == 100){ |
|||
$('#tasks_edittaskform #complete').show(); |
|||
}else{ |
|||
$('#tasks_edittaskform #complete').hide(); |
|||
} |
|||
}); |
|||
|
|||
$('#tasks_edittaskform input[type="submit"]').live('click',function(){ |
|||
$.post('ajax/edittask.php',$('#tasks_edittaskform').serialize(),function(jsondata){ |
|||
$('.error_msg').remove(); |
|||
$('.error').removeClass('error'); |
|||
if(jsondata.status == 'success'){ |
|||
var id = jsondata.data.id; |
|||
$('#task_details').data('id',id); |
|||
$('#task_details').html(jsondata.data.page); |
|||
var task = jsondata.data.task; |
|||
$('#tasks .task[data-id='+id+']') |
|||
.data('task', task) |
|||
.html(OC.Tasks.create_task_div(task).html()); |
|||
} |
|||
else{ |
|||
var errors = jsondata.data.errors; |
|||
for (k in errors){ |
|||
$('#'+k).addClass('error') |
|||
.after('<span class="error_msg">'+errors[k]+'</span>'); |
|||
} |
|||
$('.error_msg').effect('highlight', {}, 3000); |
|||
$('.error').effect('highlight', {}, 3000); |
|||
} |
|||
}, 'json'); |
|||
return false; |
|||
}); |
|||
|
|||
OCCategories.app = 'calendar'; |
|||
}); |
|||
@ -0,0 +1,187 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud - Calendar |
|||
* |
|||
* @author Bart Visscher |
|||
* @copyright 2011 Bart Visscher bartv@thisnet.nl |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
/** |
|||
* This class manages our tasks |
|||
*/ |
|||
OC_Task_App::$l10n = new OC_L10N('tasks'); |
|||
class OC_Task_App { |
|||
public static $l10n; |
|||
|
|||
public static function getPriorityOptions() |
|||
{ |
|||
return array( |
|||
'' => self::$l10n->t('Unspecified'), |
|||
'1' => self::$l10n->t('1=highest'), |
|||
'2' => '2', |
|||
'3' => '3', |
|||
'4' => '4', |
|||
'5' => self::$l10n->t('5=medium'), |
|||
'6' => '6', |
|||
'7' => '7', |
|||
'8' => '8', |
|||
'9' => self::$l10n->t('9=lowest'), |
|||
); |
|||
} |
|||
|
|||
public static function arrayForJSON($id, $vtodo, $user_timezone) |
|||
{ |
|||
$task = array( 'id' => $id ); |
|||
$task['summary'] = $vtodo->getAsString('SUMMARY'); |
|||
$task['description'] = $vtodo->getAsString('DESCRIPTION'); |
|||
$task['location'] = $vtodo->getAsString('LOCATION'); |
|||
$task['categories'] = $vtodo->getAsArray('CATEGORIES'); |
|||
$due = $vtodo->DUE; |
|||
if ($due) { |
|||
$task['due_date_only'] = $due->getDateType() == Sabre_VObject_Element_DateTime::DATE; |
|||
$due = $due->getDateTime(); |
|||
$due->setTimezone(new DateTimeZone($user_timezone)); |
|||
$task['due'] = $due->format('U'); |
|||
} |
|||
else { |
|||
$task['due'] = false; |
|||
} |
|||
$task['priority'] = $vtodo->getAsString('PRIORITY'); |
|||
$completed = $vtodo->COMPLETED; |
|||
if ($completed) { |
|||
$completed = $completed->getDateTime(); |
|||
$completed->setTimezone(new DateTimeZone($user_timezone)); |
|||
$task['completed'] = $completed->format('Y-m-d H:i:s'); |
|||
} |
|||
else { |
|||
$task['completed'] = false; |
|||
} |
|||
$task['complete'] = $vtodo->getAsString('PERCENT-COMPLETE'); |
|||
return $task; |
|||
} |
|||
|
|||
public static function validateRequest($request) |
|||
{ |
|||
$errors = array(); |
|||
if($request['summary'] == ''){ |
|||
$errors['summary'] = self::$l10n->t('Empty Summary'); |
|||
} |
|||
|
|||
try { |
|||
$timezone = OCP\Config::getUserValue(OCP\User::getUser(), "calendar", "timezone", "Europe/London"); |
|||
$timezone = new DateTimeZone($timezone); |
|||
new DateTime($request['due'], $timezone); |
|||
} catch (Exception $e) { |
|||
$errors['due'] = self::$l10n->t('Invalid date/time'); |
|||
} |
|||
|
|||
if ($request['percent_complete'] < 0 || $request['percent_complete'] > 100){ |
|||
$errors['percent_complete'] = self::$l10n->t('Invalid percent complete'); |
|||
} |
|||
if ($request['percent_complete'] == 100 && !empty($request['completed'])){ |
|||
try { |
|||
$timezone = OCP\Config::getUserValue(OCP\User::getUser(), "calendar", "timezone", "Europe/London"); |
|||
$timezone = new DateTimeZone($timezone); |
|||
new DateTime($request['completed'], $timezone); |
|||
} catch (Exception $e) { |
|||
$errors['completed'] = self::$l10n->t('Invalid date/time'); |
|||
} |
|||
} |
|||
|
|||
$priority_options = self::getPriorityOptions(); |
|||
if (!in_array($request['priority'], array_keys($priority_options))) { |
|||
$errors['priority'] = self::$l10n->t('Invalid priority'); |
|||
} |
|||
return $errors; |
|||
} |
|||
|
|||
public static function createVCalendarFromRequest($request) |
|||
{ |
|||
$vcalendar = new OC_VObject('VCALENDAR'); |
|||
$vcalendar->add('PRODID', 'ownCloud Calendar'); |
|||
$vcalendar->add('VERSION', '2.0'); |
|||
|
|||
$vtodo = new OC_VObject('VTODO'); |
|||
$vcalendar->add($vtodo); |
|||
|
|||
$vtodo->setDateTime('CREATED', 'now', Sabre_VObject_Element_DateTime::UTC); |
|||
|
|||
$vtodo->setUID(); |
|||
return self::updateVCalendarFromRequest($request, $vcalendar); |
|||
} |
|||
|
|||
public static function updateVCalendarFromRequest($request, $vcalendar) |
|||
{ |
|||
$summary = $request['summary']; |
|||
$categories = $request["categories"]; |
|||
$priority = $request['priority']; |
|||
$percent_complete = $request['percent_complete']; |
|||
$completed = $request['completed']; |
|||
$location = $request['location']; |
|||
$due = $request['due']; |
|||
$description = $request['description']; |
|||
|
|||
$vtodo = $vcalendar->VTODO; |
|||
|
|||
$vtodo->setDateTime('LAST-MODIFIED', 'now', Sabre_VObject_Element_DateTime::UTC); |
|||
$vtodo->setDateTime('DTSTAMP', 'now', Sabre_VObject_Element_DateTime::UTC); |
|||
$vtodo->setString('SUMMARY', $summary); |
|||
|
|||
$vtodo->setString('LOCATION', $location); |
|||
$vtodo->setString('DESCRIPTION', $description); |
|||
$vtodo->setString('CATEGORIES', $categories); |
|||
$vtodo->setString('PRIORITY', $priority); |
|||
|
|||
if ($due) { |
|||
$timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
$timezone = new DateTimeZone($timezone); |
|||
$due = new DateTime($due, $timezone); |
|||
$vtodo->setDateTime('DUE', $due); |
|||
} else { |
|||
unset($vtodo->DUE); |
|||
} |
|||
|
|||
self::setComplete($vtodo, $percent_complete, $completed); |
|||
|
|||
return $vcalendar; |
|||
} |
|||
|
|||
public static function setComplete($vtodo, $percent_complete, $completed) |
|||
{ |
|||
if (!empty($percent_complete)) { |
|||
$vtodo->setString('PERCENT-COMPLETE', $percent_complete); |
|||
}else{ |
|||
$vtodo->__unset('PERCENT-COMPLETE'); |
|||
} |
|||
|
|||
if ($percent_complete == 100){ |
|||
if (!$completed){ |
|||
$completed = 'now'; |
|||
} |
|||
} else { |
|||
$completed = null; |
|||
} |
|||
if ($completed) { |
|||
$timezone = OCP\Config::getUserValue(OCP\User::getUser(), 'calendar', 'timezone', date_default_timezone_get()); |
|||
$timezone = new DateTimeZone($timezone); |
|||
$completed = new DateTime($completed, $timezone); |
|||
$vtodo->setDateTime('COMPLETED', $completed); |
|||
} else { |
|||
unset($vtodo->COMPLETED); |
|||
} |
|||
} |
|||
} |
|||
@ -0,0 +1,27 @@ |
|||
<?php |
|||
/** |
|||
* ownCloud - Calendar |
|||
* |
|||
* @author Bart Visscher |
|||
* @copyright 2011 Bart Visscher bartv@thisnet.nl |
|||
* |
|||
* This library is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE |
|||
* License as published by the Free Software Foundation; either |
|||
* version 3 of the License, or any later version. |
|||
* |
|||
* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details. |
|||
* |
|||
* You should have received a copy of the GNU Affero General Public |
|||
* License along with this library. If not, see <http://www.gnu.org/licenses/>. |
|||
* |
|||
*/ |
|||
|
|||
/** |
|||
* This class manages our tasks |
|||
*/ |
|||
class OC_Task_VTodo extends OC_Calendar_Object{ |
|||
} |
|||
@ -0,0 +1,15 @@ |
|||
<form id="tasks_addtaskform"> |
|||
<?php if(count($_['calendars'])==1): ?>
|
|||
<input type="hidden" name="id" value="<?php echo $_['calendars'][0]['id']; ?>"> |
|||
<?php else: ?>
|
|||
<label for="id"><?php echo $l->t('Calendar'); ?></label>
|
|||
<select name="id" size="1"> |
|||
<?php foreach($_['calendars'] as $calendar): ?>
|
|||
<option value="<?php echo $calendar['id']; ?>"><?php echo $calendar['displayname']; ?></option>
|
|||
<?php endforeach; ?>
|
|||
</select> |
|||
<br> |
|||
<?php endif; ?>
|
|||
<?php echo $this->inc('part.taskform'); ?>
|
|||
<input type="submit" name="submit" value="<?php echo $l->t('Create Task'); ?>"> |
|||
</form> |
|||
@ -0,0 +1,42 @@ |
|||
<?php if(isset($_['details']->SUMMARY)): ?>
|
|||
<table> |
|||
<?php |
|||
echo $this->inc('part.property', array('label' => $l->t('Summary'), 'property' => $_['details']->SUMMARY)); |
|||
if(isset($_['details']->LOCATION)): |
|||
echo $this->inc('part.property', array('label' => $l->t('Location'), 'property' => $_['details']->LOCATION)); |
|||
endif; |
|||
if(isset($_['details']->CATEGORIES)): |
|||
echo $this->inc('part.property', array('label' => $l->t('Categories'), 'property' => $_['details']->CATEGORIES)); |
|||
endif; |
|||
if(isset($_['details']->DUE)): |
|||
echo $this->inc('part.property', array('label' => $l->t('Due'), 'property' => $_['details']->DUE[0])); |
|||
endif; |
|||
if(isset($_['details']->PRIORITY)): |
|||
echo $this->inc('part.property', array('label' => $l->t('Priority'), 'property' => $_['details']->PRIORITY[0], 'options' => $_['priority_options'])); |
|||
endif; |
|||
if($_['details']->__isset('PERCENT-COMPLETE') || isset($_['details']->COMPLETED)): |
|||
?>
|
|||
<tr> |
|||
<th> |
|||
<?php echo $l->t('Complete') ?>
|
|||
</th> |
|||
<td> |
|||
<?php if($_['details']->__isset('PERCENT-COMPLETE')): |
|||
echo $_['details']->__get('PERCENT-COMPLETE')->value.' % '; |
|||
endif; |
|||
if(isset($_['details']->COMPLETED)): |
|||
echo $l->t('on '). $l->l('datetime', $_['details']->COMPLETED[0]->getDateTime()); |
|||
endif; |
|||
echo '</tr>'; |
|||
endif; |
|||
if(isset($_['details']->DESCRIPTION)): |
|||
echo $this->inc('part.property', array('label' => $l->t('Description'), 'property' => $_['details']->DESCRIPTION)); |
|||
endif; ?>
|
|||
</table> |
|||
<form> |
|||
<input type="button" id="tasks_delete" value="<?php echo $l->t('Delete');?>"> |
|||
<input type="button" id="tasks_edit" value="<?php echo $l->t('Edit');?>"> |
|||
</form> |
|||
<?php else: ?>
|
|||
<?php //var_dump($_['details']); ?>
|
|||
<?php endif ?>
|
|||
@ -0,0 +1,5 @@ |
|||
<form id="tasks_edittaskform"> |
|||
<input type="hidden" name="id" value="<?php echo $_['id']; ?>"> |
|||
<?php echo $this->inc('part.taskform'); ?>
|
|||
<input type="submit" name="submit" value="<?php echo $l->t('Update Task'); ?>"> |
|||
</form> |
|||
@ -0,0 +1,22 @@ |
|||
<tr> |
|||
<th> |
|||
<?php echo $_['label'] ?>
|
|||
</th> |
|||
<td> |
|||
<?php |
|||
switch (get_class($_['property'])) |
|||
{ |
|||
case 'Sabre_VObject_Element_DateTime': |
|||
echo $l->l('datetime', $_['property']->getDateTime()); |
|||
break; |
|||
default: |
|||
$value = $_['property']->value; |
|||
if (isset($_['options'])) |
|||
{ |
|||
$value = $_['options'][$value]; |
|||
} |
|||
echo nl2br($value); |
|||
} |
|||
?>
|
|||
</td> |
|||
</tr> |
|||
@ -0,0 +1,36 @@ |
|||
<label for="summary"><?php echo $l->t('Summary'); ?></label>
|
|||
<input type="text" id="summary" name="summary" placeholder="<?php echo $l->t('Summary of the task');?>" value="<?php echo isset($_['details']->SUMMARY) ? $_['details']->SUMMARY[0]->value : '' ?>"> |
|||
<br> |
|||
<label for="location"><?php echo $l->t('Location'); ?></label>
|
|||
<input type="text" id="location" name="location" placeholder="<?php echo $l->t('Location of the task');?>" value="<?php echo isset($_['details']->LOCATION) ? $_['details']->LOCATION[0]->value : '' ?>"> |
|||
<br> |
|||
<label for="categories"><?php echo $l->t('Categories'); ?></label>
|
|||
<input id="categories" name="categories" type="text" placeholder="<?php echo $l->t('Separate categories with commas'); ?>" value="<?php echo isset($_['categories']) ? htmlspecialchars($_['categories']) : '' ?>"> |
|||
<a class="action edit" onclick="$(this).tipsy('hide');OCCategories.edit();" title="<?php echo $l->t('Edit categories'); ?>"><img alt="<?php echo $l->t('Edit categories'); ?>" src="<?php echo image_path('core','actions/rename.svg')?>" class="svg action" style="width: 16px; height: 16px;"></a> |
|||
<br> |
|||
<label for="due"><?php echo $l->t('Due'); ?></label>
|
|||
<input type="text" id="due" name="due" placeholder="<?php echo $l->t('Due date') ?>" value="<?php echo isset($_['details']->DUE) ? $l->l('datetime', $_['details']->DUE[0]->getDateTime()) : '' ?>"> |
|||
<br> |
|||
<select name="percent_complete" id="percent_complete"> |
|||
<?php |
|||
foreach($_['percent_options'] as $percent){ |
|||
echo '<option value="' . $percent . '"' . (($_['details']->__get('PERCENT-COMPLETE') && $percent == $_['details']->__get('PERCENT-COMPLETE')->value) ? ' selected="selected"' : '') . '>' . $percent . ' %</option>'; |
|||
} |
|||
?>
|
|||
</select> |
|||
<label for="percent_complete"><?php echo $l->t('Complete'); ?></label>
|
|||
<span id="complete"<?php echo ($_['details']->__get('PERCENT-COMPLETE') && $_['details']->__get('PERCENT-COMPLETE')->value == 100) ? '' : ' style="display:none;"' ?>><label for="completed"><?php echo $l->t('completed on'); ?></label>
|
|||
<input type="text" id="completed" name="completed" value="<?php echo isset($_['details']->COMPLETED) ? $l->l('datetime', $_['details']->COMPLETED[0]->getDateTime()) : '' ?>"></span> |
|||
<br> |
|||
<label for="priority"><?php echo $l->t('Priority'); ?></label>
|
|||
<select name="priority"> |
|||
<?php |
|||
foreach($_['priority_options'] as $priority => $label){ |
|||
echo '<option value="' . $priority . '"' . ((isset($_['details']->PRIORITY) && $priority == $_['details']->PRIORITY->value) ? ' selected="selected"' : '') . '>' . $label . '</option>'; |
|||
} |
|||
?>
|
|||
</select> |
|||
<br> |
|||
<label for="description"><?php echo $l->t('Description'); ?></label><br>
|
|||
<textarea placeholder="<?php echo $l->t('Description of the task');?>" name="description"><?php echo isset($_['details']->DESCRIPTION) ? $_['details']->DESCRIPTION[0]->value : '' ?></textarea>
|
|||
<br> |
|||
@ -0,0 +1,3 @@ |
|||
<?php foreach( $_['tasks'] as $task ): ?>
|
|||
<li data-id="<?php echo $task['id']; ?>"><a href="index.php?id=<?php echo $task['id']; ?>"><?php echo $task['name']; ?></a> </li>
|
|||
<?php endforeach; ?>
|
|||
@ -0,0 +1,31 @@ |
|||
<div id="controls"> |
|||
<input type="text" id="tasks_newtask"> |
|||
<input type="button" id="tasks_addtask" value="<?php echo $l->t('Add Task'); ?>"> |
|||
<input type="button" id="tasks_order_due" value="<?php echo $l->t('Order Due'); ?>"> |
|||
<input type="button" id="tasks_order_category" value="<?php echo $l->t('Order Category'); ?>"> |
|||
<input type="button" id="tasks_order_complete" value="<?php echo $l->t('Order Complete'); ?>"> |
|||
<input type="button" id="tasks_order_location" value="<?php echo $l->t('Order Location'); ?>"> |
|||
<input type="button" id="tasks_order_prio" value="<?php echo $l->t('Order Priority'); ?>"> |
|||
<input type="button" id="tasks_order_label" value="<?php echo $l->t('Order Label'); ?>"> |
|||
</div> |
|||
<div id="tasks_lists" class="leftcontent"> |
|||
<div class="all">All</div> |
|||
<div class="done">Done</div> |
|||
</div> |
|||
<div id="tasks_list" class="rightcontent"> |
|||
<p class="loading"><?php echo $l->t('Loading tasks...') ?></p>
|
|||
</div> |
|||
<p id="task_actions_template" class="task_actions"> |
|||
<!-- span class="task_star"> |
|||
<img title="<?php echo $l->t('Important') ?>" src="<?php echo image_path('core', 'actions/add.svg') ?>" class="svg"><?php echo $l->t('Important') ?>
|
|||
</span --> |
|||
<span class="task_more"> |
|||
<img title="<?php echo $l->t('More') ?>" src="<?php echo image_path('core', 'actions/triangle-s.svg') ?>" class="svg"><?php echo $l->t('More') ?>
|
|||
</span> |
|||
<span class="task_less"> |
|||
<img title="<?php echo $l->t('Less') ?>" src="<?php echo image_path('core', 'actions/triangle-n.svg') ?>" class="svg"><?php echo $l->t('Less') ?>
|
|||
</span> |
|||
</p> |
|||
<script type='text/javascript'> |
|||
var categories = <?php echo json_encode($_['categories']); ?>;
|
|||
</script> |
|||
|
After Width: 16 | Height: 16 | Size: 470 B |
@ -0,0 +1,92 @@ |
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
|||
<!-- Created with Inkscape (http://www.inkscape.org/) --> |
|||
|
|||
<svg |
|||
xmlns:dc="http://purl.org/dc/elements/1.1/" |
|||
xmlns:cc="http://creativecommons.org/ns#" |
|||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" |
|||
xmlns:svg="http://www.w3.org/2000/svg" |
|||
xmlns="http://www.w3.org/2000/svg" |
|||
xmlns:xlink="http://www.w3.org/1999/xlink" |
|||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" |
|||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" |
|||
width="16px" |
|||
height="16px" |
|||
id="svg6077" |
|||
version="1.1" |
|||
inkscape:version="0.48.3.1 r9886" |
|||
sodipodi:docname="triangle-n.svg" |
|||
inkscape:export-filename="triangle-n.png" |
|||
inkscape:export-xdpi="90" |
|||
inkscape:export-ydpi="90"> |
|||
<defs |
|||
id="defs6079"> |
|||
<linearGradient |
|||
inkscape:collect="always" |
|||
xlink:href="#linearGradient3587-6-5-3-4-5-4-0-1" |
|||
id="linearGradient7308" |
|||
gradientUnits="userSpaceOnUse" |
|||
gradientTransform="matrix(0,-0.54681372,-0.39376081,0,14.87048,24.63452)" |
|||
x1="34.992828" |
|||
y1="0.94087797" |
|||
x2="34.992828" |
|||
y2="33.955856" /> |
|||
<linearGradient |
|||
id="linearGradient3587-6-5-3-4-5-4-0-1"> |
|||
<stop |
|||
offset="0" |
|||
style="stop-color:#000000;stop-opacity:1" |
|||
id="stop3589-9-2-2-3-2-53-4-3" /> |
|||
<stop |
|||
offset="1" |
|||
style="stop-color:#363636;stop-opacity:1" |
|||
id="stop3591-7-4-73-7-9-86-9-3" /> |
|||
</linearGradient> |
|||
</defs> |
|||
<sodipodi:namedview |
|||
id="base" |
|||
pagecolor="#ffffff" |
|||
bordercolor="#666666" |
|||
borderopacity="1.0" |
|||
inkscape:pageopacity="0.0" |
|||
inkscape:pageshadow="2" |
|||
inkscape:zoom="22.197802" |
|||
inkscape:cx="-6.9113863" |
|||
inkscape:cy="8" |
|||
inkscape:current-layer="layer1" |
|||
showgrid="true" |
|||
inkscape:grid-bbox="true" |
|||
inkscape:document-units="px" |
|||
inkscape:window-width="1920" |
|||
inkscape:window-height="1025" |
|||
inkscape:window-x="-2" |
|||
inkscape:window-y="-3" |
|||
inkscape:window-maximized="1" /> |
|||
<metadata |
|||
id="metadata6082"> |
|||
<rdf:RDF> |
|||
<cc:Work |
|||
rdf:about=""> |
|||
<dc:format>image/svg+xml</dc:format> |
|||
<dc:type |
|||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> |
|||
<dc:title></dc:title> |
|||
</cc:Work> |
|||
</rdf:RDF> |
|||
</metadata> |
|||
<g |
|||
id="layer1" |
|||
inkscape:label="Layer 1" |
|||
inkscape:groupmode="layer"> |
|||
<path |
|||
inkscape:connector-curvature="0" |
|||
d="M 14.5,15 1.5,15 8,3 14.5,15 z" |
|||
id="path2843-0-1-6-6" |
|||
style="opacity:0.6;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
|||
<path |
|||
inkscape:connector-curvature="0" |
|||
d="m 14.5,13.49996 -13,0 6.49999,-12 6.50001,12 z" |
|||
id="path2843-39-5-5" |
|||
style="opacity:0.7;color:#000000;fill:url(#linearGradient7308);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" /> |
|||
</g> |
|||
</svg> |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue