+ *
+ * @license GNU AGPL version 3 or any later version
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+app.directive('timepicker', function() {
+ 'use strict';
+ return {
+ restrict: 'A',
+ link: function(scope, elm, attr) {
+ return elm.timepicker({
+ onSelect: function(date, inst) {
+ scope.setDuedateTime(moment("2000-01-01 " + date));
+ scope.$apply();
+ },
+ myPosition: 'center top',
+ atPosition: 'center bottom',
+ hourText: t('deck', 'Hours'),
+ minuteText: t('deck', 'Minutes'),
+ showPeriodLabels: false
+ });
+ }
+ };
+});
diff --git a/js/filters/relativeDateFilter.js b/js/filters/dateFilters.js
similarity index 63%
rename from js/filters/relativeDateFilter.js
rename to js/filters/dateFilters.js
index 95e780558..0c8d3e3ce 100644
--- a/js/filters/relativeDateFilter.js
+++ b/js/filters/dateFilters.js
@@ -25,3 +25,33 @@ app.filter('relativeDateFilter', function() {
return OC.Util.relativeModifiedDate(timestamp*1000);
}
});
+
+app.filter('relativeDateFilterString', function() {
+ return function (date) {
+ return OC.Util.relativeModifiedDate(Date.parse(date));
+ }
+});
+
+app.filter('dateToTimestamp', function() {
+ return function (date) {
+ return Date.parse(date);
+ }
+});
+
+app.filter('parseDate', function() {
+ return function (date) {
+ if(moment(date).isValid()) {
+ return moment(date).format('YYYY-MM-DD');
+ }
+ return "";
+ }
+});
+
+app.filter('parseTime', function() {
+ return function (date) {
+ if(moment(date).isValid()) {
+ return moment(date).format('HH:mm');
+ }
+ return "";
+ }
+});
\ No newline at end of file
diff --git a/lib/Controller/CardController.php b/lib/Controller/CardController.php
index b18ceec73..4e9b52739 100644
--- a/lib/Controller/CardController.php
+++ b/lib/Controller/CardController.php
@@ -90,8 +90,8 @@ class CardController extends Controller {
* @param $description
* @return \OCP\AppFramework\Db\Entity
*/
- public function update($id, $title, $stackId, $type, $order, $description) {
- return $this->cardService->update($id, $title, $stackId, $type, $order, $description, $this->userId);
+ public function update($id, $title, $stackId, $type, $order, $description, $duedate) {
+ return $this->cardService->update($id, $title, $stackId, $type, $order, $description, $this->userId, $duedate);
}
/**
diff --git a/lib/Db/BoardMapper.php b/lib/Db/BoardMapper.php
index 0c16d9d6c..a1f2b2a92 100644
--- a/lib/Db/BoardMapper.php
+++ b/lib/Db/BoardMapper.php
@@ -140,7 +140,6 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
$timeLimit = time()-(60*5);
$sql = 'SELECT id, title, owner, color, archived, deleted_at FROM `*PREFIX*deck_boards` ' .
'WHERE `deleted_at` > 0 AND `deleted_at` < ?';
- \OC::$server->getLogger()->error($sql);
return $this->findEntities($sql, [$timeLimit]);
}
@@ -216,4 +215,4 @@ class BoardMapper extends DeckMapper implements IPermissionMapper {
}
-}
\ No newline at end of file
+}
diff --git a/lib/Db/Card.php b/lib/Db/Card.php
index 53f73771d..e1f581acf 100644
--- a/lib/Db/Card.php
+++ b/lib/Db/Card.php
@@ -24,6 +24,7 @@
// db/author.php
namespace OCA\Deck\Db;
+use DateTime;
use JsonSerializable;
class Card extends RelationalEntity implements JsonSerializable {
@@ -39,6 +40,12 @@ class Card extends RelationalEntity implements JsonSerializable {
protected $owner;
protected $order;
protected $archived = false;
+ protected $duedate = null;
+
+ const DUEDATE_FUTURE = 0;
+ const DUEDATE_NEXT = 1;
+ const DUEDATE_NOW = 2;
+ const DUEDATE_OVERDUE = 3;
public function __construct() {
$this->addType('id', 'integer');
@@ -51,4 +58,33 @@ class Card extends RelationalEntity implements JsonSerializable {
$this->addResolvable('owner');
}
+ public function jsonSerialize() {
+ $json = parent::jsonSerialize();
+ $json['overdue'] = self::DUEDATE_FUTURE;
+ $due = strtotime($this->duedate);
+
+ $today = new DateTime();
+ $today->setTime( 0, 0, 0 );
+
+ $match_date = new DateTime($this->duedate);
+
+ $match_date->setTime( 0, 0, 0 );
+
+ $diff = $today->diff( $match_date );
+ $diffDays = (integer)$diff->format( "%R%a" ); // Extract days count in interval
+
+ if($due !== false) {
+ if ($diffDays === 1) {
+ $json['overdue'] = self::DUEDATE_NEXT;
+ }
+ if ($diffDays === 0) {
+ $json['overdue'] = self::DUEDATE_NOW;
+ }
+ if ($diffDays < 0) {
+ $json['overdue'] = self::DUEDATE_OVERDUE;
+ }
+ }
+ return $json;
+ }
+
}
diff --git a/lib/Service/CardService.php b/lib/Service/CardService.php
index d841d02bc..5cfaa4097 100644
--- a/lib/Service/CardService.php
+++ b/lib/Service/CardService.php
@@ -50,9 +50,6 @@ class CardService {
return $card;
}
- /**
- * @param integer $order
- */
public function create($title, $stackId, $type, $order, $owner) {
$this->permissionService->checkPermission($this->stackMapper, $stackId, Acl::PERMISSION_EDIT);
if($this->boardService->isArchived($this->stackMapper, $stackId)) {
@@ -76,7 +73,7 @@ class CardService {
return $this->cardMapper->delete($this->cardMapper->find($id));
}
- public function update($id, $title, $stackId, $type, $order, $description, $owner) {
+ public function update($id, $title, $stackId, $type, $order, $description, $owner, $duedate) {
$this->permissionService->checkPermission($this->cardMapper, $id, Acl::PERMISSION_EDIT);
if($this->boardService->isArchived($this->cardMapper, $id)) {
throw new StatusException('Operation not allowed. This board is archived.');
@@ -91,6 +88,7 @@ class CardService {
$card->setOrder($order);
$card->setOwner($owner);
$card->setDescription($description);
+ $card->setDuedate($duedate);
return $this->cardMapper->update($card);
}
diff --git a/templates/main.php b/templates/main.php
index f2e675ed5..4728dbf19 100644
--- a/templates/main.php
+++ b/templates/main.php
@@ -36,16 +36,17 @@ Util::addScript('deck', 'vendor/angular-ui-select/dist/select.min');
Util::addScript('deck', 'vendor/markdown-it/dist/markdown-it.min');
Util::addScript('deck', 'vendor/angular-markdown-it/dist/ng-markdownit.min');
Util::addScript('deck', 'vendor/markdown-it-link-target/dist/markdown-it-link-target.min');
+Util::addScript('deck', 'vendor/jquery-timepicker/jquery.ui.timepicker');
-if(!\OC::$server->getConfig()->getSystemValue('debug', false)) {
+if(true && !\OC::$server->getConfig()->getSystemValue('debug', false)) {
Util::addScript('deck', 'public/app');
} else {
// Load seperate JS files when debug mode is enabled
$js = [
'app' => ['App', 'Config', 'Run'],
'controller' => ['AppController', 'BoardController', 'CardController', 'ListController'],
- 'directive' => ['appnavigationentryutils', 'appPopoverMenuUtils', 'autofocusoninsert', 'avatar', 'elastic', 'search'],
- 'filters' => ['boardFilterAcl', 'cardFilter', 'cardSearchFilter', 'iconWhiteFilter', 'lightenColorFilter', 'orderObjectBy', 'relativeDateFilter', 'textColorFilter'],
+ 'directive' => ['appnavigationentryutils', 'appPopoverMenuUtils', 'autofocusoninsert', 'avatar', 'elastic', 'search', 'datepicker', 'timepicker'],
+ 'filters' => ['boardFilterAcl', 'cardFilter', 'cardSearchFilter', 'iconWhiteFilter', 'lightenColorFilter', 'orderObjectBy', 'dateFilters', 'textColorFilter'],
'service' => ['ApiService', 'BoardService', 'CardService', 'LabelService', 'StackService', 'StatusService'],
];
foreach($js as $folder=>$files) {
diff --git a/templates/part.board.mainView.php b/templates/part.board.mainView.php
index 51c5b1bec..bc32f1b43 100644
--- a/templates/part.board.mainView.php
+++ b/templates/part.board.mainView.php
@@ -68,6 +68,9 @@
+ {{ c.duedate | relativeDateFilterString }}