Remove dependency of appframework app

This commit is contained in:
raimund-schluessler 2014-04-06 01:09:35 +02:00
parent 9fbae4fc81
commit f7a8ba09c2
26 changed files with 2638 additions and 1249 deletions

View file

@ -22,38 +22,46 @@
*/
namespace OCA\Tasks_enhanced;
use \OCA\AppFramework\Core\API;
use \OC\AppFramework\Core\API;
// dont break owncloud when the appframework is not enabled
if(\OCP\App::isEnabled('appframework') && \OCP\App::isEnabled('calendar')){
if(\OCP\App::isEnabled('calendar')){
$api = new API('tasks_enhanced');
// $api = new API('tasks_enhanced');
$api->addNavigationEntry(array(
// $api->addNavigationEntry(array(
// the string under which your app will be referenced in owncloud
'id' => $api->getAppName(),
// // the string under which your app will be referenced in owncloud
// 'id' => $api->getAppName(),
// sorting weight for the navigation. The higher the number, the higher
// will it be listed in the navigation
'order' => 100,
// // sorting weight for the navigation. The higher the number, the higher
// // will it be listed in the navigation
// 'order' => 100,
// the route that will be shown on startup
'href' => $api->linkToRoute('tasks_enhanced_index'),
// // the route that will be shown on startup
// 'href' => $api->linkToRoute('tasks_enhanced_index'),
// the icon that will be shown in the navigation
// this file needs to exist in img/example.png
'icon' => $api->imagePath('tasks.svg'),
// // the icon that will be shown in the navigation
// // this file needs to exist in img/example.png
// 'icon' => $api->imagePath('tasks.svg'),
// 'icon' => $api->imagePath('core', 'places/music.svg'),
// // 'icon' => $api->imagePath('core', 'places/music.svg'),
// the title of your application. This will be used in the
// navigation or on the settings page of your app
'name' => $api->getTrans()->t('Tasks')
// // the title of your application. This will be used in the
// // navigation or on the settings page of your app
// 'name' => $api->getTrans()->t('Tasks')
));
// ));
\OC::$server->getNavigationManager()->add(array(
'id' => 'tasks_enhanced',
'order' => 100,
'href' => \OCP\Util::linkToRoute('tasks_enhanced_index'),
'icon' => \OCP\Util::imagePath( 'tasks_enhanced', 'tasks.svg' ),
'name' => \OCP\Util::getL10N('tasks_enhanced')->t('Tasks')
)
);
} else {
$msg = 'Can not enable the Tasks app because the App Framework App or the Calendar App is disabled.';
$msg = 'Can not enable the Tasks app because the Calendar App is disabled.';
\OCP\Util::writeLog('tasks_enhanced', $msg, \OCP\Util::ERROR);
}

View file

@ -1,10 +1,9 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
* @copyright 2014 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -20,118 +19,184 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Tasks_enhanced;
use \OCA\AppFramework\App;
use OCA\Tasks_enhanced\Dispatcher;
use \OCA\Tasks_enhanced\DependencyInjection\DIContainer;
$this->create('tasks_enhanced_index', '/')->get()->action(
function($params){
// call the index method on the class PageController
App::main('PageController', 'index', $params, new DIContainer());
}
);
//define the routes
$this->create('tasks_enhanced_index', '/')
->get()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('PageController', 'index');
}
);
/*
* Lists
*/
$this->create('getLists', '/lists')->get()->action(
function($params){
App::main('ListsController', 'getLists', $params, new DIContainer());
}
);
$this->create('getLists', '/lists')
->get()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('ListsController', 'getLists');
}
);
$this->create('list_add', '/lists/add/{name}')->post()->action(
function($params){
App::main('ListsController', 'addList', $params, new DIContainer());
}
);
$this->create('list_add', '/lists/add/{name}')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('ListsController', 'addList');
}
);
$this->create('list_delete', '/lists/{listID}/delete')->post()->action(
function($params){
App::main('ListsController', 'deleteList', $params, new DIContainer());
}
);
$this->create('list_delete', '/lists/{listID}/delete')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('ListsController', 'deleteList');
}
);
$this->create('list_name', '/lists/{listID}/name')->post()->action(
function($params){
App::main('ListsController', 'setListName', $params, new DIContainer());
}
);
$this->create('list_name', '/lists/{listID}/name')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('ListsController', 'setListName');
}
);
/*
* Tasks
*/
$this->create('getTasks', '/tasks')->get()->action(
function($params){
App::main('TasksController', 'getTasks', $params, new DIContainer());
}
);
$this->create('getTasks', '/tasks')
->get()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'getTasks');
}
);
$this->create('task_star', '/tasks/{taskID}/star')->post()->action(
function($params){
App::main('TasksController', 'starTask', $params, new DIContainer());
}
);
$this->create('task_unstar', '/tasks/{taskID}/unstar')->post()->action(
function($params){
App::main('TasksController', 'unstarTask', $params, new DIContainer());
}
);
$this->create('task_star', '/tasks/{taskID}/star')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'starTask');
}
);
$this->create('task_complete', '/tasks/{taskID}/complete')->post()->action(
function($params){
App::main('TasksController', 'completeTask', $params, new DIContainer());
}
);
$this->create('task_unstar', '/tasks/{taskID}/unstar')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'unstarTask');
}
);
$this->create('task_uncomplete', '/tasks/{taskID}/uncomplete')->post()->action(
function($params){
App::main('TasksController', 'uncompleteTask', $params, new DIContainer());
}
);
$this->create('task_complete', '/tasks/{taskID}/complete')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'completeTask');
}
);
$this->create('task_add', '/tasks/add/{calendarID}/{name}')->post()->action(
function($params){
App::main('TasksController', 'addTask', $params, new DIContainer());
}
);
$this->create('task_uncomplete', '/tasks/{taskID}/uncomplete')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'uncompleteTask');
}
);
$this->create('task_delete', '/tasks/{taskID}/delete')->post()->action(
function($params){
App::main('TasksController', 'deleteTask', $params, new DIContainer());
}
);
$this->create('task_add', '/tasks/add/{calendarID}/{name}')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'addTask');
}
);
$this->create('task_name', '/tasks/{taskID}/name')->post()->action(
function($params){
App::main('TasksController', 'setTaskName', $params, new DIContainer());
}
);
$this->create('task_delete', '/tasks/{taskID}/delete')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'deleteTask');
}
);
$this->create('task_calendar', '/tasks/{taskID}/calendar')->post()->action(
function($params){
App::main('TasksController', 'setTaskCalendar', $params, new DIContainer());
}
);
$this->create('task_name', '/tasks/{taskID}/name')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'setTaskName');
}
);
$this->create('task_note', '/tasks/{taskID}/note')->post()->action(
function($params){
App::main('TasksController', 'setTaskNote', $params, new DIContainer());
}
);
$this->create('task_calendar', '/tasks/{taskID}/calendar')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'setTaskCalendar');
}
);
$this->create('task_due', '/tasks/{taskID}/due')->post()->action(
function($params){
App::main('TasksController', 'setDueDate', $params, new DIContainer());
}
);
$this->create('task_note', '/tasks/{taskID}/note')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'setTaskNote');
}
);
$this->create('task_reminder', '/tasks/{taskID}/reminder')->post()->action(
function($params){
App::main('TasksController', 'setReminderDate', $params, new DIContainer());
}
);
$this->create('task_due', '/tasks/{taskID}/due')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'setDueDate');
}
);
$this->create('task_reminder', '/tasks/{taskID}/reminder')
->post()
->action(
function($params){
\OC::$session->close();
$dispatcher = new Dispatcher($params);
$dispatcher->dispatch('TasksController', 'setReminderDate');
}
);

View file

@ -1,72 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\BusinessLayer;
use \OCA\AppFramework\Db\DoesNotExistException;
use \OCA\AppFramework\Db\MultipleObjectsReturnedException;
use \OCA\Tasks_enhanced\Db\IMapper;
abstract class BusinessLayer {
protected $mapper;
public function __construct(IMapper $mapper){
$this->mapper = $mapper;
}
/**
* Delete an entity
* @param int $id the id of the entity
* @param string $userId the name of the user for security reasons
* @throws DoesNotExistException if the entity does not exist
* @throws MultipleObjectsReturnedException if more than one entity exists
*/
public function delete($id, $userId){
$entity = $this->find($id, $userId);
$this->mapper->delete($entity);
}
/**
* Finds an entity by id
* @param int $id the id of the entity
* @param string $userId the name of the user for security reasons
* @throws DoesNotExistException if the entity does not exist
* @throws MultipleObjectsReturnedException if more than one entity exists
* @return Entity the entity
*/
public function find($id, $userId){
try {
return $this->mapper->find($id, $userId);
} catch(DoesNotExistException $ex){
throw new BusinessLayerException($ex->getMessage());
} catch(MultipleObjectsReturnedException $ex){
throw new BusinessLayerException($ex->getMessage());
}
}
}

View file

@ -1,100 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\BusinessLayer;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Utility\TimeFactory;
use \OCA\Tasks_enhanced\Db\ListsMapper;
class ListsBusinessLayer extends BusinessLayer {
private $api;
public function __construct(ListsMapper $listsMapper,
API $api
){
parent::__construct($listsMapper);
$this->api = $api;
}
public function getAllLists($userId) {
return $this->mapper->getAllLists($userId);
}
public function addList($listName,$userId){
if(trim($listName) == '') {
// OCP\JSON::error(array('message'=>'empty'));
exit;
}
$calendars = $this->api->getAllCalendars($userId);
foreach($calendars as $cal) {
if($cal['displayname'] == $listName) {
// OCP\JSON::error(array('message'=>'namenotavailable'));
exit;
}
}
$color = '#CCCCCC';
$calendarId = $this->api->addCalendar($userId,$listName,$color);
$this->api->setCalendarActive($calendarId);
$calendar = $this->api->findCalendar($calendarId);
return $calendar;
}
public function deleteList($listId){
try {
$del = $this->api->deleteCalendar($listId);
if($del == true) {
return true;
}else{
return array('error'=>'dberror');
}
} catch(Exception $e) {
return array('message'=>$e->getMessage());
}
}
public function editList($calendarId,$listName,$userId){
if(trim($listName) == '') {
// OCP\JSON::error(array('message'=>'empty'));
exit;
}
$calendars = $this->api->getAllCalendars($userId);
foreach($calendars as $cal) {
if($cal['userid'] != $userId){
continue;
}
if($cal['displayname'] == $listName && $cal['id'] != $calendarId) {
// OCP\JSON::error(array('message'=>'namenotavailable'));
exit;
}
}
$color = '#CCCCCC';
$this->api->editCalendar($calendarId,$listName,$color);
$calendar = $this->api->findCalendar($calendarId);
return $calendar;
}
}

View file

@ -1,199 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\BusinessLayer;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Utility\TimeFactory;
use \OCA\Tasks_enhanced\Db\TasksMapper;
class TasksBusinessLayer extends BusinessLayer {
private $api;
private $timeFactory;
private $autoPurgeMinimumInterval;
public function __construct(TasksMapper $tasksMapper,
API $api
){
parent::__construct($tasksMapper);
$this->api = $api;
}
public function getInitialTasks($userId) {
return $this->mapper->getInitialTasks($userId);
}
public function getAllTasks($userId) {
return $this->mapper->getAllTasks($userId);
}
public function star($taskId, $isStarred){
try {
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
if($isStarred){
$vtodo->setString('PRIORITY',1);
}else{
$vtodo->__unset('PRIORITY');
}
$this->api->editCalendarObject($taskId, $vcalendar);
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
public function complete($taskId, $isCompleted, $percent_complete){
try {
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
if (!empty($percent_complete)) {
$vtodo->setString('PERCENT-COMPLETE', $percent_complete);
}else{
$vtodo->__unset('PERCENT-COMPLETE');
}
if ($percent_complete == 100) {
if (!$isCompleted) {
$isCompleted = 'now';
}
} else {
$isCompleted = null;
}
if ($isCompleted) {
$timezone = $this->api->getTimezone();
$timezone = new \DateTimeZone($timezone);
$isCompleted = new \DateTime($isCompleted, $timezone);
$vtodo->setDateTime('COMPLETED', $isCompleted);
} else {
unset($vtodo->COMPLETED);
}
$this->api->editCalendarObject($taskId, $vcalendar);
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
public function add($taskName, $calendarId, $starred, $due){
$calendars = $this->api->getAllCalendars($this->api->getUserId());
$user_timezone = $this->api->getTimezone($this->api->getUserId());
$request = array(
'summary' => $taskName,
'categories' => null,
'priority' => $starred,
'location' => null,
'due' => $due,
'description' => null
);
$vcalendar = $this->api->createVCalendarFromRequest($request);
$taskId = $this->api->addCalendarObject($calendarId, $vcalendar);
$task = $this->api->arrayForJSON($taskId, $vcalendar->VTODO, $user_timezone);
$task['calendarid'] = $calendarId;
return $task;
}
public function setName($taskId, $name){
try {
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('SUMMARY', $name);
$this->api->editCalendarObject($taskId, $vcalendar);
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
public function setCalendar($taskId, $calendar){
try {
$data = $this->api->getEventObject($taskId);
if ($data['calendarid'] != $calendar) {
$this->api->moveToCalendar($taskId, $calendar);
}
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
public function setNote($taskId, $note){
try {
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('DESCRIPTION', $note);
$this->api->editCalendarObject($taskId, $vcalendar);
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
public function setDue($taskId, $due, $due_date_only){
try{
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
$type = null;
if ($due != 'false') {
$timezone = $this->api->getTimezone();
$timezone = new \DateTimeZone($timezone);
$due = new \DateTime('@'.$due);
$due->setTimezone($timezone);
$type = \Sabre\VObject\Property\DateTime::LOCALTZ;
if ($due_date_only) {
$type = \Sabre\VObject\Property\DateTime::DATE;
}
}
} catch (\Exception $e) {
}
$vtodo->setDateTime('DUE', $due, $type);
$this->api->editCalendarObject($taskId, $vcalendar);
}
public function setReminder(){
}
public function setCategories($taskId, $categories){
try {
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('CATEGORIES', $categories);
$this->api->editCalendarObject($taskId, $vcalendar);
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
public function setLocation($taskId, $location){
try {
$vcalendar = $this->mapper->findByID($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('LOCATION', $location);
$this->api->editCalendarObject($taskId, $vcalendar);
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
}

View file

@ -1,92 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Controller;
use \OCA\AppFramework\Controller\Controller;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Http\Request;
use \OCA\Tasks_enhanced\BusinessLayer\ListsBusinessLayer;
class ListsController extends Controller {
private $listsBusinessLayer;
public function __construct(API $api, Request $request,
ListsBusinessLayer $listsBusinessLayer){
parent::__construct($api, $request);
$this->listsBusinessLayer = $listsBusinessLayer;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function getLists(){
$lists = $this->listsBusinessLayer->getAllLists($this->api->getUserId());
$result = array(
'lists' => $lists
);
return $this->renderJSON($result);
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function addList(){
$listName = $this->params('name');
$list = $this->listsBusinessLayer->addList($listName,$this->api->getUserId());
$list['tmpID'] = $this->params('tmpID');
$result = array(
'list' => $list
);
return $this->renderJSON($result);
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function deleteList(){
$listId = $this->params('listID');
$result = $this->listsBusinessLayer->deleteList($listId);
return $this->renderJSON();
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setListName(){
$listId = (int) $this->params('listID');
$listName = $this->params('name');
$result = $this->listsBusinessLayer->editList($listId, $listName,$this->api->getUserId());
return $this->renderJSON($result);
}
}

View file

@ -1,57 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Controller;
use \OCA\AppFramework\Controller\Controller;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Http\Request;
class PageController extends Controller {
public function __construct(API $api, Request $request){
parent::__construct($api, $request);
}
/**
* ATTENTION!!!
* The following comments turn off security checks
* Please look up their meaning in the documentation!
*
* @CSRFExemption
* @IsAdminExemption
* @IsSubAdminExemption
*/
public function index(){
$date = new \DateTimeZone(\OC_Calendar_App::getTimezone());
$day = new \DateTime('today', $date);
$day = $day->format('d');
return $this->render('main', array(
'DOM' => $day
));
}
}

View file

@ -1,214 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Controller;
use \OCA\AppFramework\Controller\Controller;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Http\Request;
use \OCA\Tasks_enhanced\BusinessLayer\TasksBusinessLayer;
class TasksController extends Controller {
private $tasksBusinessLayer;
public function __construct(API $api, Request $request,
TasksBusinessLayer $tasksBusinessLayer){
parent::__construct($api, $request);
$this->tasksBusinessLayer = $tasksBusinessLayer;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function getTasks(){
$tasks = $this->tasksBusinessLayer->getAllTasks($this->api->getUserId());
$result = array(
'tasks' => $tasks
);
return $this->renderJSON($result);
}
private function setStarred($isStarred){
$taskID = (int) $this->params('taskID');
$this->tasksBusinessLayer->star($taskID, $isStarred);
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function starTask(){
try {
$this->setStarred(true);
return $this->renderJSON();
} catch(\Exception $e) {
return $this->renderJSON(array(), $e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function unstarTask(){
try {
$this->setStarred(false);
return $this->renderJSON();
} catch(\Exception $e) {
return $this->renderJSON(array(), $e->getMessage());
}
}
private function setCompleted($isCompleted){
$taskId = (int) $this->params('taskID');
$this->tasksBusinessLayer->complete($taskId, null, $isCompleted ? '100' : '0');
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function completeTask(){
try {
$this->setCompleted(true);
return $this->renderJSON();
} catch(\Exception $e) {
return $this->renderJSON(array(), $e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function uncompleteTask(){
try {
$this->setCompleted(false);
return $this->renderJSON();
} catch(\Exception $e) {
return $this->renderJSON(array(), $e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function addTask(){
$taskName = $this->params('name');
$calendarID = $this->params('calendarID');
$starred = $this->params('starred');
$due = $this->params('due');
$task = $this->tasksBusinessLayer->add($taskName, $calendarID, $starred, $due);
$task['tmpID'] = $this->params('tmpID');
$result = array(
'task' => $task
);
return $this->renderJSON($result);
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function deleteTask(){
$taskId = $this->params('taskID');
$task = $this->api->getEventObject($taskId);
$this->api->deleteCalendarObject($taskId);
return $this->renderJSON();
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setTaskName(){
$taskId = (int) $this->params('taskID');
$taskName = $this->params('name');
$this->tasksBusinessLayer->setName($taskId, $taskName);
return $this->renderJSON();
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setTaskCalendar(){
$taskId = $this->params('taskID');
$calendarId = $this->params('calendarID');
$this->tasksBusinessLayer->setCalendar($taskId, $calendarId);
return $this->renderJSON();
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setTaskNote(){
$taskId = $this->params('taskID');
$note = $this->params('note');
$this->tasksBusinessLayer->setNote($taskId, $note);
return $this->renderJSON();
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setDueDate(){
$taskId = $this->params('taskID');
$due = $this->params('due');
$date = 1;
$this->tasksBusinessLayer->setDue($taskId, $due, $date);
return $this->renderJSON();
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setReminderDate(){
$taskID = $this->params('taskID');
$reminder = $this->params('reminder');
$this->tasksBusinessLayer->setReminder($taskId, $due);
return $this->renderJSON();
}
}

View file

@ -1,28 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Db;
interface IMapper {
public function find($id, $userId);
}

View file

@ -1,54 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Db;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Db\Mapper;
use \OCA\AppFramework\Db\Entity;
class ListsMapper extends Mapper implements IMapper {
public function __construct(API $api) {
parent::__construct($api, 'lists');
}
public function find($id, $userId){
// $sql = 'SELECT * FROM `*PREFIX*news_folders` ' .
// 'WHERE `id` = ? ' .
// 'AND `user_id` = ?';
// $row = $this->findOneQuery($sql, array($id, $userId));
// $folder = new Folder();
// $folder->fromRow($row);
// return $folder;
}
public function getAllLists($userId){
$calendar = new \OC_Calendar_Calendar();
$lists = $calendar::allCalendars($userId, true);
return $lists;
}
}

View file

@ -1,107 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Db;
use \OCA\AppFramework\Core\API;
use \OCA\AppFramework\Db\Mapper;
use \OCA\AppFramework\Db\Entity;
class TasksMapper extends Mapper implements IMapper {
public function __construct(API $api) {
parent::__construct($api, 'tasks');
}
public function find($id, $userId){
// $sql = 'SELECT * FROM `*PREFIX*news_folders` ' .
// 'WHERE `id` = ? ' .
// 'AND `user_id` = ?';
// $row = $this->findOneQuery($sql, array($id, $userId));
// $folder = new Folder();
// $folder->fromRow($row);
// return $folder;
}
public function getAllTasks($userId){
$calendars = $this->api->getAllCalendars($userId);
$user_timezone = $this->api->getTimezone($userId);
$tasks = array();
foreach( $calendars as $calendar ) {
$calendar_tasks = $this->api->getAllTasks($calendar['id']);
foreach( $calendar_tasks as $task ) {
if($task['objecttype']!='VTODO') {
continue;
}
if(is_null($task['summary'])) {
continue;
}
$vtodo = $this->api->parseVTODO($task['calendardata']);
try {
$task_data = $this->api->arrayForJSON($task['id'], $vtodo, $user_timezone);
$task_data['calendarid'] = $calendar['id'];
$tasks[] = $task_data;
} catch(\Exception $e) {
\OCP\Util::writeLog('tasks_enhanced', $e->getMessage(), \OCP\Util::ERROR);
}
}
}
return $tasks;
}
public function getInitialTasks($userId){
$calendars = $this->api->getAllCalendars($userId);
$user_timezone = $this->api->getTimezone($userId);
$tasks = array();
foreach( $calendars as $calendar ) {
$calendar_tasks = $this->api->getAllTasks($calendar['id']);
foreach( $calendar_tasks as $task ) {
if($task['objecttype']!='VTODO') {
continue;
}
if(is_null($task['summary'])) {
continue;
}
$vtodo = $this->api->parseVTODO($task['calendardata']);
if(!$vtodo->COMPLETED){
try {
$task_data = $this->api->arrayForJSON($task['id'], $vtodo, $user_timezone);
$task_data['calendarid'] = $calendar['id'];
$tasks[] = $task_data;
} catch(\Exception $e) {
\OCP\Util::writeLog('tasks_enhanced', $e->getMessage(), \OCP\Util::ERROR);
}
}
}
}
return $tasks;
}
public function findByID($taskID){
return $this->api->getVCalendar($taskID);
}
}

View file

@ -1,89 +0,0 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\DependencyInjection;
use \OCA\AppFramework\DependencyInjection\DIContainer as BaseContainer;
use \OCA\Tasks_enhanced\Controller\PageController;
use \OCA\Tasks_enhanced\Controller\ListsController;
use \OCA\Tasks_enhanced\Controller\TasksController;
use \OCA\Tasks_enhanced\BusinessLayer\ListsBusinessLayer;
use \OCA\Tasks_enhanced\BusinessLayer\TasksBusinessLayer;
use \OCA\Tasks_enhanced\Db\ListsMapper;
use \OCA\Tasks_enhanced\Db\TasksMapper;
use \OCA\Tasks_enhanced\Core\API;
class DIContainer extends BaseContainer {
public function __construct(){
parent::__construct('tasks_enhanced');
$this['API'] = $this->share(function($c){
return new API($c['AppName']);
});
// use this to specify the template directory
$this['TwigTemplateDirectory'] = __DIR__ . '/../templates';
$this['PageController'] = $this->share(function($c){
return new PageController($c['API'], $c['Request']);
});
$this['ListsController'] = $this->share(function($c){
return new ListsController($c['API'], $c['Request'],
$c['ListsBusinessLayer']);
});
$this['TasksController'] = $this->share(function($c){
return new TasksController($c['API'], $c['Request'],
$c['TasksBusinessLayer']);
});
$this['ListsBusinessLayer'] = $this->share(function($c){
return new ListsBusinessLayer(
$c['ListsMapper'],
$c['API']);
});
$this['TasksBusinessLayer'] = $this->share(function($c){
return new TasksBusinessLayer(
$c['TasksMapper'],
$c['API']);
});
$this['ListsMapper'] = $this->share(function($c){
return new ListsMapper($c['API']);
});
$this['TasksMapper'] = $this->share(function($c){
return new TasksMapper($c['API']);
});
}
}

View file

@ -38,8 +38,6 @@ angular.module('Tasks',['OC','ngRoute'])
redirectTo: '/lists/all'
})
$interpolateProvider.startSymbol('[[')
$interpolateProvider.endSymbol(']]')
###
overwrite angular's directive ngSwitchWhen
to handle ng-switch-when="value1 || value2 || value3

View file

@ -22,8 +22,6 @@
$routeProvider.when('/lists/:listID', {}).when('/lists/:listID/edit/:listparameter', {}).when('/lists/:listID/tasks/:taskID', {}).when('/lists/:listID/tasks/:taskID/edit/:parameter', {}).when('/search/:searchString', {}).when('/search/:searchString/tasks/:taskID', {}).when('/search/:searchString/tasks/:taskID/edit/:parameter', {}).otherwise({
redirectTo: '/lists/all'
});
$interpolateProvider.startSymbol('[[');
$interpolateProvider.endSymbol(']]');
/*
overwrite angular's directive ngSwitchWhen
to handle ng-switch-when="value1 || value2 || value3

1728
js/vendor/appframework/app.js vendored Normal file

File diff suppressed because it is too large Load diff

44
lib/controller.php Normal file
View file

@ -0,0 +1,44 @@
<?php
/**
* @author Thomas Tanghus
* @author Thomas Tanghus
* @copyright 2013-2014 Thomas Tanghus (thomas@tanghus.net)
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Tasks_enhanced;
use OCP\AppFramework\IAppContainer,
OCP\AppFramework\Controller as BaseController,
OCP\IRequest;
/**
* Base Controller class for Issues App
*/
class Controller extends BaseController {
/**
* @var Api
*/
protected $api;
/**
* @var IRequest
*/
protected $request;
/**
* @var OCP\IServerContainer
*/
protected $server;
public function __construct(IAppContainer $container) {
$this->api = $container->query('API');
$this->request = $container->query('Request');
$this->server = $container->getServer();
}
}

View file

@ -0,0 +1,144 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Controller;
use OCA\Tasks_enhanced\Controller,
OCP\AppFramework\Http\JSONResponse;
class ListsController extends Controller {
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function getLists(){
$userId = $this->api->getUserId();
$calendar = new \OC_Calendar_Calendar();
$lists = $calendar::allCalendars($userId, true);
$result = array(
'data' => array(
'lists' => $lists
)
);
$response = new JSONResponse();
$response->setData($result);
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function addList(){
$listName = $this->params('name');
$userId = $this->api->getUserId();
if(trim($listName) == '') {
// OCP\JSON::error(array('message'=>'empty'));
exit;
}
$calendars = \OC_Calendar_Calendar::allCalendars($userId, true);
foreach($calendars as $cal) {
if($cal['displayname'] == $listName) {
// OCP\JSON::error(array('message'=>'namenotavailable'));
exit;
}
}
$color = '#CCCCCC';
$calendarId = \OC_Calendar_Calendar::addCalendar($userId, strip_tags($listName), 'VEVENT,VTODO,VJOURNAL', null, 0, $color);
\OC_Calendar_Calendar::setCalendarActive($calendarId, 1);
$list = \OC_Calendar_Calendar::find($calendarId);
$list['tmpID'] = $this->params('tmpID');
$result = array(
'data' => array(
'list' => $list
)
);
$response = new JSONResponse();
$response->setData($result);
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function deleteList(){
$listId = $this->params('listID');
$response = new JSONResponse();
try {
$del = \OC_Calendar_Calendar::deleteCalendar($listId);
if($del == true) {
$result = array(
'data' => array()
);
}else{
$result = array('error'=>'dberror');
}
} catch(Exception $e) {
$result = array('message'=>$e->getMessage());
}
$response->setData($result);
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setListName(){
$listId = (int) $this->params('listID');
$listName = $this->params('name');
$userId = $this->api->getUserId();
$response = new JSONResponse();
if(trim($listName) == '') {
// OCP\JSON::error(array('message'=>'empty'));
exit;
}
$calendars = \OC_Calendar_Calendar::allCalendars($userId, true);
foreach($calendars as $cal) {
if($cal['userid'] != $userId){
continue;
}
if($cal['displayname'] == $listName && $cal['id'] != $listId) {
// OCP\JSON::error(array('message'=>'namenotavailable'));
exit;
}
}
$color = '#CCCCCC';
\OC_Calendar_Calendar::editCalendar($listId, strip_tags($listName), null, null, null, $color);
$result = array(
'data' => array()
);
$response->setData($result);
return $response;
}
}

View file

@ -0,0 +1,49 @@
<?php
/**
* @author Thomas Tanghus
* @copyright 2014 Thomas Tanghus (thomas@tanghus.net)
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Tasks_enhanced\Controller;
use OCA\Tasks_enhanced\Controller,
OCP\AppFramework\Http\TemplateResponse;
/**
* Controller class for main page.
*/
class PageController extends Controller {
/**
* @NoAdminRequired
* @NoCSRFRequired
*/
public function index() {
if (defined('DEBUG') && DEBUG) {
\OCP\Util::addScript('tasks_enhanced', 'vendor/angularjs/angular');
\OCP\Util::addScript('tasks_enhanced', 'vendor/angularjs/angular-route');
\OCP\Util::addScript('tasks_enhanced', 'vendor/momentjs/moment');
} else {
\OCP\Util::addScript('tasks_enhanced', 'vendor/angularjs/angular.min');
\OCP\Util::addScript('tasks_enhanced', 'vendor/angularjs/angular-route.min');
\OCP\Util::addScript('tasks_enhanced', 'vendor/momentjs/moment.min');
}
\OCP\Util::addScript('tasks_enhanced', 'public/app');
\OCP\Util::addScript('tasks_enhanced', 'vendor/appframework/app');
\OCP\Util::addScript('tasks_enhanced', 'vendor/timepicker/jquery.ui.timepicker');
\OCP\Util::addStyle('tasks_enhanced', 'style');
// TODO: Make a HTMLTemplateResponse class
$response = new TemplateResponse('tasks_enhanced', 'main');
/*$response->setParams(array(
'var' => $var,
));*/
return $response;
}
}

View file

@ -0,0 +1,387 @@
<?php
/**
* ownCloud - Tasks
*
* @author Raimund Schlüßler
* @copyright 2013 Raimund Schlüßler raimund.schluessler@googlemail.com
*
* 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/>.
*
*/
namespace OCA\Tasks_enhanced\Controller;
use OCA\Tasks_enhanced\Controller,
OCA\Tasks_enhanced\Helper,
OCP\AppFramework\Http\JSONResponse;
class TasksController extends Controller {
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function getTasks(){
$userId = $this->api->getUserId();
$calendars = \OC_Calendar_Calendar::allCalendars($userId, true);
$user_timezone = \OC_Calendar_App::getTimezone();
$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;
}
$vtodo = Helper::parseVTODO($task['calendardata']);
try {
$task_data = Helper::arrayForJSON($task['id'], $vtodo, $user_timezone);
$task_data['calendarid'] = $calendar['id'];
$tasks[] = $task_data;
} catch(\Exception $e) {
\OCP\Util::writeLog('tasks_enhanced', $e->getMessage(), \OCP\Util::ERROR);
}
}
}
$result = array(
'data' => array(
'tasks' => $tasks
)
);
$response = new JSONResponse();
$response->setData($result);
return $response;
}
private function setStarred($isStarred){
$taskId = (int) $this->params('taskID');
try {
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
if($isStarred){
$vtodo->setString('PRIORITY',1);
}else{
$vtodo->__unset('PRIORITY');
}
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function starTask(){
$response = new JSONResponse();
try {
$this->setStarred(true);
return $response;
} catch(\Exception $e) {
return $response;
// return $this->renderJSON(array(), $e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function unstarTask(){
$response = new JSONResponse();
try {
$this->setStarred(false);
return $response;
} catch(\Exception $e) {
return $response;
// return $this->renderJSON(array(), $e->getMessage());
}
}
private function setCompleted($isCompleted){
$taskId = (int) $this->params('taskID');
$percent_complete = $isCompleted ? '100' : '0';
$isCompleted = null;
try {
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
if (!empty($percent_complete)) {
$vtodo->setString('PERCENT-COMPLETE', $percent_complete);
}else{
$vtodo->__unset('PERCENT-COMPLETE');
}
if ($percent_complete == 100) {
if (!$isCompleted) {
$isCompleted = 'now';
}
} else {
$isCompleted = null;
}
if ($isCompleted) {
$timezone = \OC_Calendar_App::getTimezone();
$timezone = new \DateTimeZone($timezone);
$isCompleted = new \DateTime($isCompleted, $timezone);
$vtodo->setDateTime('COMPLETED', $isCompleted);
} else {
unset($vtodo->COMPLETED);
}
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function completeTask(){
$response = new JSONResponse();
try {
$this->setCompleted(true);
return $response;
} catch(\Exception $e) {
return $response;
// return $this->renderJSON(array(), $e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function uncompleteTask(){
$response = new JSONResponse();
try {
$this->setCompleted(false);
return $response;
} catch(\Exception $e) {
return $response;
// return $this->renderJSON(array(), $e->getMessage());
}
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function addTask(){
$taskName = $this->params('name');
$calendarId = $this->params('calendarID');
$starred = $this->params('starred');
$due = $this->params('due');
$response = new JSONResponse();
$userId = $this->api->getUserId();
$calendars = \OC_Calendar_Calendar::allCalendars($userId, true);
$user_timezone = \OC_Calendar_App::getTimezone();
$request = array(
'summary' => $taskName,
'categories' => null,
'priority' => $starred,
'location' => null,
'due' => $due,
'description' => null
);
$vcalendar = Helper::createVCalendarFromRequest($request);
$taskId = \OC_Calendar_Object::add($calendarId, $vcalendar->serialize());
$task = Helper::arrayForJSON($taskId, $vcalendar->VTODO, $user_timezone);
$task['calendarid'] = $calendarId;
$task['tmpID'] = $this->params('tmpID');
$result = array(
'data' => array(
'task' => $task
)
);
$response->setData($result);
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function deleteTask(){
$response = new JSONResponse();
$taskId = $this->params('taskID');
$task = \OC_Calendar_App::getEventObject($taskId);
\OC_Calendar_Object::delete($taskId);
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setTaskName(){
$taskId = (int) $this->params('taskID');
$taskName = $this->params('name');
$response = new JSONResponse();
try {
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('SUMMARY', $taskName);
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setTaskCalendar(){
$taskId = $this->params('taskID');
$calendarId = $this->params('calendarID');
$response = new JSONResponse();
try {
$data = \OC_Calendar_App::getEventObject($taskId);
if ($data['calendarid'] != $calendar) {
\OC_Calendar_Object::moveToCalendar($taskId, $calendarId);
}
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setTaskNote(){
$taskId = $this->params('taskID');
$note = $this->params('note');
$response = new JSONResponse();
try {
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('DESCRIPTION', $note);
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setDueDate(){
$taskId = $this->params('taskID');
$due = $this->params('due');
$response = new JSONResponse();
$date = 1;
try{
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
$type = null;
if ($due != 'false') {
$timezone = \OC_Calendar_App::getTimezone();
$timezone = new \DateTimeZone($timezone);
$due = new \DateTime('@'.$due);
$due->setTimezone($timezone);
$type = \Sabre\VObject\Property\DateTime::LOCALTZ;
if ($due_date_only) {
$type = \Sabre\VObject\Property\DateTime::DATE;
}
}
} catch (\Exception $e) {
}
$vtodo->setDateTime('DUE', $due, $type);
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setReminderDate(){
$taskID = $this->params('taskID');
$reminder = $this->params('reminder');
$response = new JSONResponse();
//TODO
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setCategories($taskId, $categories){
$taskId = $this->params('taskID');
$categories = $this->params('categories');
$response = new JSONResponse();
try {
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('CATEGORIES', $categories);
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
return $response;
}
/**
* @IsAdminExemption
* @IsSubAdminExemption
* @Ajax
*/
public function setLocation($taskId, $location){
$taskId = $this->params('taskID');
$location = $this->params('location');
$response = new JSONResponse();
try {
$vcalendar = \OC_Calendar_App::getVCalendar($taskId);
$vtodo = $vcalendar->VTODO;
$vtodo->setString('LOCATION', $location);
\OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
} catch(\Exception $e) {
// throw new BusinessLayerException($e->getMessage());
}
return $response;
}
}

49
lib/dispatcher.php Normal file
View file

@ -0,0 +1,49 @@
<?php
/**
* @author Thomas Tanghus
* @copyright 2013-2014 Thomas Tanghus (thomas@tanghus.net)
*
* This file is licensed under the Affero General Public License version 3 or
* later.
* See the COPYING-README file.
*/
namespace OCA\Tasks_enhanced;
use OCP\AppFramework\App as MainApp,
OCP\AppFramework\IAppContainer,
OCA\Tasks_enhanced\Controller\PageController,
OCA\Tasks_enhanced\Controller\ListsController,
OCA\Tasks_enhanced\Controller\TasksController;
/**
* This class manages our app actions
*
* TODO: Merge with App
*/
class Dispatcher extends MainApp {
/**
* @var App
*/
protected $app;
public function __construct($params) {
parent::__construct('tasks_enhanced', $params);
$this->container = $this->getContainer();
$this->registerServices();
}
public function registerServices() {
$this->container->registerService('PageController', function(IAppContainer $container) {
return new PageController($container);
});
$this->container->registerService('ListsController', function(IAppContainer $container) {
return new ListsController($container);
});
$this->container->registerService('TasksController', function(IAppContainer $container) {
return new TasksController($container);
});
}
}

View file

@ -1,10 +1,9 @@
<?php
/**
* ownCloud - Music app
* ownCloud - Utility class for VObject properties
*
* @author Morris Jobke
* @copyright 2013 Morris Jobke <morris.jobke@gmail.com>
* @author Thomas Tanghus
* @copyright 2013-2014 Thomas Tanghus (thomas@tanghus.net)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@ -21,14 +20,13 @@
*
*/
namespace OCA\Tasks_enhanced;
namespace OCA\Tasks_enhanced\Core;
// use OCA\Tasks_enhanced\App;
use \OCA\AppFramework\Core\API as BaseAPI;
Class helper {
class API extends BaseAPI {
public function parseVTODO($data) {
public static function parseVTODO($data) {
$object = \OC_VObject::parse($data);
$vtodo = $object->VTODO;
return $vtodo;
@ -90,61 +88,6 @@ class API extends BaseAPI {
return $task;
}
public static function getAllCalendars($userId){
return \OC_Calendar_Calendar::allCalendars($userId, true);
}
public static function deleteCalendar($calendarId){
return \OC_Calendar_Calendar::deleteCalendar($calendarId);
}
public static function addCalendar($userId,$listName,$color){
return \OC_Calendar_Calendar::addCalendar($userId, strip_tags($listName), 'VEVENT,VTODO,VJOURNAL', null, 0, $color);
}
public static function setCalendarActive($calendarId){
return \OC_Calendar_Calendar::setCalendarActive($calendarId, 1);
}
public static function editCalendar($calendarId,$listName,$color) {
return \OC_Calendar_Calendar::editCalendar($calendarId, strip_tags($listName), null, null, null, $color);
}
public static function findCalendar($calendarId){
return \OC_Calendar_Calendar::find($calendarId);
}
public static function getTimezone(){
return \OC_Calendar_App::getTimezone();
}
public static function getVCalendar($taskId){
return \OC_Calendar_App::getVCalendar($taskId);
}
public static function getEventObject($taskID){
return \OC_Calendar_App::getEventObject($taskID);
}
public static function getAllTasks($calendarId){
return \OC_Calendar_Object::all($calendarId);
}
public static function editCalendarObject($taskId, $vcalendar){
return \OC_Calendar_Object::edit($taskId, $vcalendar->serialize());
}
public static function moveToCalendar($taskId, $calendarId){
return \OC_Calendar_Object::moveToCalendar($taskId, $calendarId);
}
public static function addCalendarObject($calendarId, $vcalendar){
return \OC_Calendar_Object::add($calendarId, $vcalendar->serialize());
}
public static function deleteCalendarObject($taskID){
return \OC_Calendar_Object::delete($taskID);
}
public static function createVCalendarFromRequest($request){
$vcalendar = new \OC_VObject('VCALENDAR');
@ -184,6 +127,4 @@ class API extends BaseAPI {
return $vcalendar;
}
}
}

View file

@ -1,13 +1,3 @@
{{ style('style', 'tasks_enhanced') }}
{{ style('jquery.ui.timepicker', 'tasks_enhanced/css/vendor/timepicker') }}
{{ script('vendor/angularjs/angular.min', 'tasks_enhanced') }}
{{ script('vendor/angularjs/angular-route.min', 'tasks_enhanced') }}
{{ script('public/app', 'appframework') }}
{{ script('vendor/momentjs/moment.min','tasks_enhanced') }}
{{ script('vendor/timepicker/jquery.ui.timepicker','tasks_enhanced') }}
{{ script('public/app','tasks_enhanced') }}
<div ng-app="Tasks" ng-cloak ng-controller="AppController" ng-click="closeAll()">
<div id="task-lists" ng-controller="ListController">
<div id="task_lists_header" class="header" ng-class="{'search': status.searchActive}" ng-controller="SearchController">
@ -21,7 +11,7 @@
</div>
<div id="search-toolbar">
<span class="icon menu-search"></span>
<input type="text" key-placeholder="placeholder_search" placeholder={{ trans('Search...') }} ng-model="searchString" ng-keyup="trySearch($event)" >
<input type="text" key-placeholder="placeholder_search" placeholder="<?php p($l->t('Search...')); ?>" ng-model="searchString" ng-keyup="trySearch($event)" >
<a id="cancel-search" ng-click="closeSearch()">
<span class="icon detail-delete"></span>
</a>
@ -29,21 +19,21 @@
</div>
<div id="task_lists_scroll" class="scroll">
<ul id="collection_filters">
<li ng-repeat="collection in collections" id="collection_[[ collection.id ]]" rel="[[ collection.id ]]"
<li ng-repeat="collection in collections" id="collection_{{ collection.id }}" rel="{{ collection.id }}"
ng-class="{'animate-up': getCollectionCount(collection.id)<1, active: collection.id==route.listID}" oc-drop-task>
<a href="#/lists/[[ collection.id ]]">
<span class="icon collection-[[ collection.id ]]"><text ng-show="collection.id=='today'">{{ DOM }}</text></span>
<span class="count">[[ getCollectionString(collection.id) ]]</span>
<span class="title"><text>{{ trans('[[ collection.displayname ]]') }}</text></span>
<a href="#/lists/{{ collection.id }}">
<span class="icon collection-{{ collection.id }}"><text ng-show="collection.id=='today'">{{ DOM }}</text></span>
<span class="count">{{ getCollectionString(collection.id) }}</span>
<span class="title"><text>{{ collection.displayname }}</text></span>
</a>
</li>
</ul>
<ul id="collection_lists">
<li ng-repeat="list in lists" id="list_[[ list.id ]]" rel="[[ list.id ]]" ng-class="{active: list.id==route.listID}" oc-drop-task>
<a href="#/lists/[[ list.id ]]">
<li ng-repeat="list in lists" id="list_{{ list.id }}" rel="{{ list.id }}" ng-class="{active: list.id==route.listID}" oc-drop-task>
<a href="#/lists/{{ list.id }}">
<span class="icon list-list"></span>
<span class="count"><text ng-show="getListCount(list.id,'all')">[[ getListCount(list.id,'all') ]]</text></span>
<span class="title"><text ng-dblclick="editName(list.id)" oc-click-focus="{selector: 'input.edit', timeout: 0}">[[ list.displayname ]]</text></span>
<span class="count"><text ng-show="getListCount(list.id,'all')">{{ getListCount(list.id,'all') }}</text></span>
<span class="title"><text ng-dblclick="editName(list.id)" oc-click-focus="{selector: 'input.edit', timeout: 0}">{{ list.displayname }}</text></span>
</a>
<input ng-model="list.displayname" class="edit" type="text" ng-show="route.listparameter=='name' && route.listID == list.id" stop-event="click"
ng-keydown="checkName($event)">
@ -51,9 +41,9 @@
</ul>
<a class="addlist" ng-click="startAddingList()" stop-event="click" oc-click-focus="{selector: '#newList', timeout: 0}">
<span class="icon detail-add"></span>
<span class="title"><text>{{ trans('Add List...') }}</text></span>
<span class="title"><text><?php p($l->t('Add List...')); ?></text></span>
<input id="newList" ng-model="status.newListName" class="edit" type="text" ng-disabled="isAddingList" ng-show="status.addingList"
stop-event="click" placeholder="{{ trans('New List') }}" ng-keydown="checkListInput($event)" />
stop-event="click" placeholder="<?php p($l->t('New List')); ?>" ng-keydown="checkListInput($event)" />
</a>
</div>
<div id="task_lists_footer" class="footer">
@ -72,14 +62,14 @@
<span class="icon input-date"></span>
</a>
<form ng-submit="addTask(taskName)" name="addTaskForm">
<input id="target" ng-disabled="isAddingTask" class="transparent" placeholder="[[ getAddString() ]]" ng-model="taskName"
<input id="target" ng-disabled="isAddingTask" class="transparent" placeholder="{{ getAddString() }}" ng-model="taskName"
ng-keydown="checkTaskInput($event)"/>
</form>
</div>
<div class="task-list" ng-class="{'completed-hidden':!status.showhidden}" ng-switch="route.listID">
{{ include('part.tasklist.php') }}
{{ include('part.collectionall.php') }}
{{ include('part.collectionweek.php') }}
<?php print_unescaped($this->inc('part.tasklist')); ?>
<?php print_unescaped($this->inc('part.collectionall')); ?>
<?php print_unescaped($this->inc('part.collectionweek')); ?>
</div>
</div>

View file

@ -1,11 +1,11 @@
<div ng-switch-when="starred || completed || all || today">
<div ng-animate="'animate'" ng-repeat="list in lists | filter:filterLists()" class="grouped-tasks ui-droppable" rel="[[ list.id ]]" oc-drop-task>
<div ng-animate="'animate'" ng-repeat="list in lists | filter:filterLists()" class="grouped-tasks ui-droppable" rel="{{ list.id }}" oc-drop-task>
<h2 class="heading">
<text>[[ list.displayname ]]</text>
<text>{{ list.displayname }}</text>
</h2>
<ol class="tasks">
<li ng-animate="'animate'" ng-repeat="task in tasks | filter:{'calendarid':list.id} | filter:filterTasks(task) | orderBy:'due' | orderBy:'starred':true"
class="task-item ui-draggable" rel="[[ task.id ]]" ng-click="openDetails(task.id)" ng-class="{done: task.completed}" oc-drag-task stop-event="click">
class="task-item ui-draggable" rel="{{ task.id }}" ng-click="openDetails(task.id)" ng-class="{done: task.completed}" oc-drag-task stop-event="click">
<div class="task-body">
<a class="task-checkbox" name="toggleCompleted" ng-click="toggleCompleted(task.id)" stop-event="click">
<span class="icon task-checkbox" ng-class="{'task-checked': task.completed}"></span>
@ -14,9 +14,9 @@
<a class="task-star" ng-click="toggleStarred(task.id)" stop-event="click">
<span class="icon task-star faded" ng-class="{'task-starred': task.starred}"></span>
</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">[[ task.due | dateTaskList ]]</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">{{ task.due | dateTaskList }}</a>
<div class="title-wrapper" ng-class="{attachment: task.note!=''}">
<span class="title">[[ task.name ]]</span>
<span class="title">{{ task.name }}</span>
<span class="icon task-attachment"></span>
</div>
</div>

View file

@ -1,11 +1,11 @@
<div ng-switch-when="week">
<div ng-animate="'animate'" ng-repeat="day in days | filter:dayHasEntry(day)" class="grouped-tasks ui-droppable" rel="[[ list.id ]]">
<div ng-animate="'animate'" ng-repeat="day in days | filter:dayHasEntry(day)" class="grouped-tasks ui-droppable" rel="{{ list.id }}">
<h2 class="heading">
<text>[[ day | day ]]</text>
<text>{{ day | day }}</text>
</h2>
<ol class="tasks">
<li ng-animate="'animate'" ng-repeat="task in tasks | taskAtDay:day | filter:{'completed':'false'} | orderBy:'due' | orderBy:'starred':true"
class="task-item ui-draggable" rel="[[ task.id ]]" ng-click="openDetails(task.id)" ng-class="{done: task.completed}" oc-drag-task stop-event="click">
class="task-item ui-draggable" rel="{{ task.id }}" ng-click="openDetails(task.id)" ng-class="{done: task.completed}" oc-drag-task stop-event="click">
<div class="task-body">
<a class="task-checkbox" name="toggleCompleted" ng-click="toggleCompleted(task.id)" stop-event="click">
<span class="icon task-checkbox" ng-class="{'task-checked': task.completed}"></span>
@ -14,9 +14,9 @@
<a class="task-star" ng-click="toggleStarred(task.id)" stop-event="click">
<span class="icon task-star faded" ng-class="{'task-starred': task.starred}"></span>
</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">[[ task.due | dateTaskList ]]</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">{{ task.due | dateTaskList }}</a>
<div class="title-wrapper" ng-class="{attachment: task.note!=''}">
<span class="title">[[ task.name ]]</span>
<span class="title">{{ task.name }}</span>
<span class="icon task-attachment"></span>
</div>
</div>

View file

@ -7,10 +7,10 @@
</a>
<div class="title">
<span class="title-text" ng-class="{'strike-through':task.completed}" ng-click="editName()" stop-event="click"
ng-hide="route.parameter=='name'" oc-click-focus="{selector: '#editName', timeout: 0}">[[ task.name ]]</span>
ng-hide="route.parameter=='name'" oc-click-focus="{selector: '#editName', timeout: 0}">{{ task.name }}</span>
<div class="expandable-container" ng-show="route.parameter=='name'" stop-event="click">
<div class="expandingArea active">
<pre><span>[[ task.name ]]</span><br /></pre>
<pre><span>{{ task.name }}</span><br /></pre>
<textarea id="editName" maxlength="200" ng-model="task.name" ng-keydown="endName($event)"></textarea>
</div>
</div>
@ -20,14 +20,14 @@
oc-click-focus="{selector: 'div.detail-date input.datepicker-input', timeout: 0}">
<span class="icon detail-date" ng-class="{'overdue':isOverDue(task.due)}"></span>
<div class="section-title" ng-class="{'overdue':isOverDue(task.due)}" ng-hide="route.parameter=='duedate'">
<text>[[ task.due | dateDetails ]]</text>
<text>{{ task.due | dateDetails }}</text>
</div>
<a class="detail-delete" ng-click="deleteDueDate()" stop-event="click">
<span class="icon detail-delete"></span>
</a>
<span class="icon detail-save" ng-click="endEdit()" stop-event="click"></span>
<div class="section-edit" ng-show="route.parameter=='duedate'">
<input class="datepicker-input medium focus" type="text" key-value="" value="[[ task.due | dateTaskList ]]" datepicker="due">
<input class="datepicker-input medium focus" type="text" key-value="" value="{{ task.due | dateTaskList }}" datepicker="due">
</div>
</div>
<!--
@ -35,15 +35,15 @@
oc-click-focus="{selector: 'div.detail-reminder input.datepicker-input', timeout: 0}">
<span class="icon detail-reminder" ng-class="{'overdue':isOverDue(task.reminder)}"></span>
<div class="section-title" ng-class="{'overdue':isOverDue(task.reminder)}" ng-hide="route.parameter=='reminder'">
<text rel="">[[ task.reminder | timeDetails ]]</text>
<text rel="">{{ task.reminder | timeDetails }}</text>
</div>
<div class="section-description">[[ task.reminder | dateDetailsShort ]]</div>
<div class="section-description">{{ task.reminder | dateDetailsShort }}</div>
<a class="detail-delete" ng-click="deleteReminder()" stop-event="click">
<span class="icon detail-delete"></span>
</a>
<span class="icon detail-save" ng-click="endEdit()" stop-event="click"></span>
<div class="section-edit" ng-show="route.parameter=='reminder'">
<input class="datepicker-input medium focus" type="text" key-value="" value="[[ task.reminder | dateTaskList ]]" datepicker="reminder">
<input class="datepicker-input medium focus" type="text" key-value="" value="{{ task.reminder | dateTaskList }}" datepicker="reminder">
</div>
</div>
<ul class="subtasks buffer">
@ -57,10 +57,10 @@
</a>
-->
<div class="content-fakeable">
<div class="display-view" ng-hide="route.parameter=='note'">[[ task.note ]]</div>
<div class="display-view" ng-hide="route.parameter=='note'">{{ task.note }}</div>
<div class="edit-view" ng-show="route.parameter=='note'">
<div class="expandingArea active">
<pre><span>[[ task.note ]]</span><br /><br /></pre>
<pre><span>{{ task.note }}</span><br /><br /></pre>
<textarea ng-model="task.note"></textarea>
</div>
</div>

View file

@ -2,7 +2,7 @@
<div class="grouped-tasks">
<ol class="tasks" rel="uncompleted" oc-drop-task>
<li ng-animate="'animate'" ng-repeat="(id, task) in tasks | filter:{'calendarid':route.listID} | filter:{'completed':'false'} | filter:route.searchString | orderBy:'due' | orderBy:'starred':true"
class="task-item ui-draggable" rel="[[ task.id ]]" ng-click="openDetails(task.id)" ng-class="{done: task.completed}" oc-drag-task stop-event="click">
class="task-item ui-draggable" rel="{{ task.id }}" ng-click="openDetails(task.id)" ng-class="{done: task.completed}" oc-drag-task stop-event="click">
<div class="task-body">
<a class="task-checkbox" name="toggleCompleted" ng-click="toggleCompleted(task.id)" stop-event="click">
<span class="icon task-checkbox" ng-class="{'task-checked': task.completed}"></span>
@ -11,9 +11,9 @@
<a class="task-star" ng-click="toggleStarred(task.id)" stop-event="click">
<span class="icon task-star faded" ng-class="{'task-starred': task.starred}"></span>
</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">[[ task.due | dateTaskList ]]</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">{{ task.due | dateTaskList }}</a>
<div class="title-wrapper" ng-class="{attachment: task.note!=''}">
<span class="title">[[ task.name ]]</span>
<span class="title">{{ task.name }}</span>
<span class="icon task-attachment"></span>
</div>
</div>
@ -21,12 +21,12 @@
</ol>
<h2 class="heading-hiddentasks" ng-show="getCount(route.listID,'completed')" ng-switch="getCount(route.listID,'completed')">
<span class="icon toggle-completed-tasks" ng-click="toggleHidden()"></span>
<text ng-switch-when="1" ng-click="toggleHidden()">{{ trans('1 Completed Task') }}</text>
<text ng-switch-default ng-click="toggleHidden()">[[ getCount(route.listID,'completed') ]] {{ trans('Completed Tasks') }}</text>
<text ng-switch-when="1" ng-click="toggleHidden()"><?php p($l->t('1 Completed Task')); ?></text>
<text ng-switch-default ng-click="toggleHidden()">{{ getCount(route.listID,'completed') }} <?php p($l->t('Completed Tasks')); ?></text>
</h2>
<ol class="completed-tasks" rel="completed" oc-drop-task>
<li ng-animate="'animate'" ng-repeat="task in tasks | filter:{'calendarid':route.listID} | filter:{'completed':'true'} | filter:route.searchString | orderBy:'completed_date':true"
class="task-item" rel="[[ task.id ]]" ng-click="openDetails(task.id)"
class="task-item" rel="{{ task.id }}" ng-click="openDetails(task.id)"
ng-class="{done: task.completed}" oc-drag-task stop-event="click">
<div class="task-body">
<a class="task-checkbox" name="toggleCompleted" ng-click="toggleCompleted(task.id)" stop-event="click">
@ -36,16 +36,16 @@
<a class="task-star" ng-click="toggleStarred(task.id)" stop-event="click">
<span class="icon task-star faded" ng-class="{'task-starred': task.starred}"></span>
</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">[[ task.due | dateTaskList ]]</a>
<a class="duedate" ng-class="{overdue: TasksModel.overdue(task.due)}">{{ task.due | dateTaskList }}</a>
<div class="title-wrapper" ng-class="{attachment: task.note!=''}">
<span class="title">[[ task.name ]]</span>
<span class="title">{{ task.name }}</span>
<span class="icon task-attachment"></span>
</div>
</div>
</li>
</ol>
<div class="loadmore">
<span ng-click="loadMore()" stop-event="click"> {{ trans('Load more completed tasks')}} </span>
<!-- <span ng-click="loadMore()" stop-event="click"> <?php p($l->t('Load more completed tasks')); ?> </span> -->
</div>
</div>
</div>