Merge branch 'tasks' for Tasks app
This commit is contained in:
commit
2facf509cc
|
@ -179,7 +179,7 @@ class OC_Calendar_App{
|
|||
foreach($events as $event) {
|
||||
$vobject = OC_VObject::parse($event['calendardata']);
|
||||
if(!is_null($vobject)) {
|
||||
$vcategories->loadFromVObject($vobject->VEVENT, true);
|
||||
self::loadCategoriesFromVCalendar($vobject);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,7 +190,16 @@ class OC_Calendar_App{
|
|||
* @see OC_VCategories::loadFromVObject
|
||||
*/
|
||||
public static function loadCategoriesFromVCalendar(OC_VObject $calendar) {
|
||||
self::getVCategories()->loadFromVObject($calendar->VEVENT, true);
|
||||
$object = null;
|
||||
if (isset($calendar->VEVENT)) {
|
||||
$object = $calendar->VEVENT;
|
||||
} else
|
||||
if (isset($calendar->VTODO)) {
|
||||
$object = $calendar->VTODO;
|
||||
}
|
||||
if ($object) {
|
||||
self::getVCategories()->loadFromVObject($object, true);
|
||||
}
|
||||
}
|
||||
|
||||
public static function getRepeatOptions(){
|
||||
|
|
|
@ -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;}
|
Binary file not shown.
After Width: | Height: | 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>
|
After Width: | Height: | Size: 3.4 KiB |
|
@ -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>
|
Binary file not shown.
After Width: | Height: | 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>
|
After Width: | Height: | Size: 3.1 KiB |
Loading…
Reference in New Issue