Add inital view of tags

This commit is contained in:
Matias De lellis
2019-11-06 11:42:30 -03:00
parent 8396e2a40a
commit b7b0158a72
10 changed files with 152 additions and 10 deletions

View File

@@ -2,6 +2,7 @@
return [ return [
'resources' => [ 'resources' => [
'note' => ['url' => '/notes'], 'note' => ['url' => '/notes'],
'tag' => ['url' => '/tags'],
'note_api' => ['url' => '/api/0.1/notes'] 'note_api' => ['url' => '/api/0.1/notes']
], ],
'routes' => [ 'routes' => [

View File

@@ -17,25 +17,41 @@ use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\JSONResponse; use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Controller; use OCP\AppFramework\Controller;
use OCA\QuickNotes\Db\Note;
use OCA\QuickNotes\Db\Color; use OCA\QuickNotes\Db\Color;
use OCA\QuickNotes\Db\NoteShare;
use OCA\QuickNotes\Db\NoteMapper;
use OCA\QuickNotes\Db\ColorMapper; use OCA\QuickNotes\Db\ColorMapper;
use OCA\QuickNotes\Db\Note;
use OCA\QuickNotes\Db\NoteMapper;
use OCA\QuickNotes\Db\NoteTag;
use OCA\QuickNotes\Db\NoteTagMapper;
use OCA\QuickNotes\Db\NoteShare;
use OCA\QuickNotes\Db\NoteShareMapper; use OCA\QuickNotes\Db\NoteShareMapper;
use OCA\QuickNotes\Db\Tag;
use OCA\QuickNotes\Db\TagMapper;
class NoteController extends Controller { class NoteController extends Controller {
private $notemapper; private $notemapper;
private $notetagmapper;
private $colormapper; private $colormapper;
private $notesharemapper; private $notesharemapper;
private $tagmapper;
private $userId; private $userId;
public function __construct($AppName, IRequest $request, NoteMapper $notemapper, NoteShareMapper $notesharemapper, ColorMapper $colormapper, $UserId) { public function __construct($AppName,
IRequest $request,
NoteMapper $notemapper,
NoteTagMapper $notetagmapper,
NoteShareMapper $notesharemapper,
ColorMapper $colormapper,
TagMapper $tagmapper,
$UserId)
{
parent::__construct($AppName, $request); parent::__construct($AppName, $request);
$this->notemapper = $notemapper; $this->notemapper = $notemapper;
$this->notetagmapper = $notetagmapper;
$this->colormapper = $colormapper; $this->colormapper = $colormapper;
$this->notesharemapper = $notesharemapper; $this->notesharemapper = $notesharemapper;
$this->tagmapper = $tagmapper;
$this->userId = $UserId; $this->userId = $UserId;
} }
@@ -56,6 +72,7 @@ class NoteController extends Controller {
} else { } else {
$note->setSharedWith(null); $note->setSharedWith(null);
} }
$note->setTags($this->tagmapper->getTagsForNote($note->getId()));
} }
$shareEntries = $this->notesharemapper->findForUser($this->userId); $shareEntries = $this->notesharemapper->findForUser($this->userId);
$shares = array(); $shares = array();

View File

@@ -0,0 +1,46 @@
<?php
/**
* Nextcloud - quicknotes
*
* This file is licensed under the Affero General Public License version 3 or
* later. See the COPYING file.
*
* @author Matias De lellis <mati86dl@gmail.com>
* @copyright Matias De lellis 2019
*/
namespace OCA\QuickNotes\Controller;
use OCP\IRequest;
use OCP\AppFramework\Http;
use OCP\AppFramework\Http\DataResponse;
use OCP\AppFramework\Http\JSONResponse;
use OCP\AppFramework\Controller;
use OCA\QuickNotes\Db\Tag;
use OCA\QuickNotes\Db\TagMapper;
class TagController extends Controller {
private $tagmapper;
private $userId;
public function __construct($AppName,
IRequest $request,
TagMapper $tagmapper,
$UserId)
{
parent::__construct($AppName, $request);
$this->tagmapper = $tagmapper;
$this->userId = $UserId;
}
/**
* @NoAdminRequired
*/
public function index() {
$notes = $this->tagmapper->findAll($this->userId);
return new DataResponse($notes);
}
}

View File

@@ -219,6 +219,13 @@ div[contenteditable="true"] {
opacity: 0.5; opacity: 0.5;
} }
.slim-tag {
display: inline-block;
padding: 3px 5px;
background-color: rgba(0,0,0,0.08);
border-radius: 12px;
}
/* Modal Content */ /* Modal Content */
.modal-content { .modal-content {

View File

@@ -14,6 +14,7 @@ class Note extends Entity implements JsonSerializable {
protected $userId; protected $userId;
protected $sharedWith; protected $sharedWith;
protected $isShared; protected $isShared;
protected $tags;
protected $color; protected $color;
@@ -31,7 +32,8 @@ class Note extends Entity implements JsonSerializable {
'color' => $this->color, 'color' => $this->color,
'userid' => $this->userId, 'userid' => $this->userId,
'sharedwith' => $this->sharedWith, 'sharedwith' => $this->sharedWith,
'isshared' => $this->isShared 'isshared' => $this->isShared,
'tags' => $this->tags
]; ];
} }
} }

View File

@@ -20,4 +20,12 @@ class TagMapper extends Mapper {
return $this->findEntities($sql, [$userId]); return $this->findEntities($sql, [$userId]);
} }
public function getTagsForNote ($noteId) {
$sql = 'SELECT T.id, T.name FROM *PREFIX*quicknotes_tags T ';
$sql.= 'INNER JOIN *PREFIX*quicknotes_note_tags NT ';
$sql.= 'ON T.id = NT.tag_id ';
$sql.= 'WHERE NT.note_id = ?';
return $this->findEntities($sql, [$noteId]);
}
} }

View File

@@ -145,9 +145,38 @@ Notes.prototype = {
} }
}; };
// this notes object holds all our tags
var Tags = function (baseUrl) {
this._baseUrl = baseUrl;
this._tags = [];
this._loaded = false;
};
Tags.prototype = {
loadAll: function () {
var deferred = $.Deferred();
var self = this;
$.get(this._baseUrl).done(function (tags) {
self._tags = tags.reverse();
self._loaded = true;
deferred.resolve();
}).fail(function () {
deferred.reject();
});
return deferred.promise();
},
isLoaded: function () {
return this._loaded;
},
getAll: function () {
return this._tags;
}
};
// this will be the view that is used to update the html // this will be the view that is used to update the html
var View = function (notes) { var View = function (notes, tags) {
this._notes = notes; this._notes = notes;
this._tags = tags;
}; };
View.prototype = { View.prototype = {
@@ -580,10 +609,12 @@ View.prototype = {
var html = Handlebars.templates['navigation']({ var html = Handlebars.templates['navigation']({
colors: this._notes.getColors(), colors: this._notes.getColors(),
notes: this._notes.getAll(), notes: this._notes.getAll(),
tags: this._tags.getAll(),
newNoteTxt: t('quicknotes', 'New note'), newNoteTxt: t('quicknotes', 'New note'),
allNotesTxt: t('quicknotes', 'All notes'), allNotesTxt: t('quicknotes', 'All notes'),
colorsTxt: t('quicknotes', 'Colors'), colorsTxt: t('quicknotes', 'Colors'),
notesTxt: t('quicknotes', 'Notes'), notesTxt: t('quicknotes', 'Notes'),
tagsTxt: t('quicknotes', 'Tags'),
}); });
$('#app-navigation ul').html(html); $('#app-navigation ul').html(html);
@@ -730,18 +761,25 @@ new OCA.Search(search, function() {
* Create modules * Create modules
*/ */
var notes = new Notes(OC.generateUrl('/apps/quicknotes/notes')); var notes = new Notes(OC.generateUrl('/apps/quicknotes/notes'));
var view = new View(notes); var tags = new Tags(OC.generateUrl('/apps/quicknotes/tags'));
var view = new View(notes, tags);
/* /*
* Render loading view * Render initial loading view
*/ */
view.renderContent(); view.renderContent();
/* /*
* Loading notes and render view. * Loading notes and render final view.
*/ */
notes.loadAll().done(function () { notes.loadAll().done(function () {
tags.loadAll().done(function () {
view.render(); view.render();
}).fail(function () {
alert('Could not load tags');
});
// FIXME: So ugly...
}).fail(function () { }).fail(function () {
alert('Could not load notes'); alert('Could not load notes');
}); });

View File

@@ -31,3 +31,14 @@
{{/each}} {{/each}}
</ul> </ul>
</li> </li>
<li id="notes-folder" class="collapsible open">
<button class="collapse"></button>
<a href="#" class="icon-folder svg">{{tagsTxt}}</a>
<ul>
{{#each tags}}
<li class="note with-menu {{#if active}}active{{/if}}" data-id="{{ id }}">
<a href="#">{{{ name }}}</a>
</li>
{{/each}}
</ul>
</li>

View File

@@ -25,6 +25,11 @@
<div class='note-content'> <div class='note-content'>
{{{ content }}} {{{ content }}}
</div> </div>
<div class='note-tags'>
{{#each tags}}
<div class="slim-tag" data-id="{{ id }}">{{{ name }}}</div>
{{/each}}
</div>
{{/if}} {{/if}}
</div> </div>
</div> </div>

View File

@@ -28,6 +28,13 @@
<div class='note-content'> <div class='note-content'>
{{{ content }}} {{{ content }}}
</div> </div>
<div class='note-tags'>
{{#each tags}}
<div class='slim-tag' data-id="{{ id }}">
{{{ name }}}
</div>
{{/each}}
</div>
{{/if}} {{/if}}
</div> </div>
</div> </div>