From 49124298a2c62655924407edd7277a2b1a6c6fff Mon Sep 17 00:00:00 2001 From: Marcin Kurczewski Date: Mon, 6 Oct 2014 21:16:59 +0200 Subject: [PATCH] Added tag listing --- TODO | 3 - public_html/css/tag-list.css | 28 +++++++ public_html/index.html | 1 + public_html/js/Presenters/TagListPresenter.js | 73 ++++++++++++++++++- public_html/js/Presenters/UserPresenter.js | 2 +- public_html/templates/tag-list-item.tpl | 5 ++ public_html/templates/tag-list.tpl | 18 +++++ src/Controllers/TagController.php | 45 ++++++++++++ src/SearchServices/Filters/TagFilter.php | 15 ++++ .../Parsers/TagSearchParser.php | 37 ++++++++++ src/Services/TagService.php | 9 +++ src/di.php | 1 + 12 files changed, 230 insertions(+), 7 deletions(-) create mode 100644 public_html/css/tag-list.css create mode 100644 public_html/templates/tag-list-item.tpl create mode 100644 public_html/templates/tag-list.tpl create mode 100644 src/Controllers/TagController.php create mode 100644 src/SearchServices/Filters/TagFilter.php create mode 100644 src/SearchServices/Parsers/TagSearchParser.php diff --git a/TODO b/TODO index 4089b68b..416ba6bd 100644 --- a/TODO +++ b/TODO @@ -29,9 +29,6 @@ everything related to tags: - automatic removal of unused tags in backend - tags.json refresh when editing post - basic tags - - listing - - sort alphabetically - - sort by time of addition - mass tag - merging - tag editing diff --git a/public_html/css/tag-list.css b/public_html/css/tag-list.css new file mode 100644 index 00000000..cdaa0858 --- /dev/null +++ b/public_html/css/tag-list.css @@ -0,0 +1,28 @@ +#tag-list { + text-align: center; +} + +#tag-list ul { + list-style-type: none; + padding: 0; + margin: 0; +} + +#ta-list ul.order { + margin: -0.5em -0.5em 0.5em -0.5em; +} +#tag-list ul.order li { + display: inline-block; + margin: 0 0.5em; +} +#tag-list ul.order a { + cursor: pointer; + display: inline-block; + padding: 0.2em 0.5em; +} + +#tag-list table { + min-width: 20em; + text-align: left; + margin: 1em auto; +} diff --git a/public_html/index.html b/public_html/index.html index 1755e82a..fd4dd036 100644 --- a/public_html/index.html +++ b/public_html/index.html @@ -39,6 +39,7 @@ + diff --git a/public_html/js/Presenters/TagListPresenter.js b/public_html/js/Presenters/TagListPresenter.js index 9f4dcfaf..f4a5ca52 100644 --- a/public_html/js/Presenters/TagListPresenter.js +++ b/public_html/js/Presenters/TagListPresenter.js @@ -2,27 +2,94 @@ var App = App || {}; App.Presenters = App.Presenters || {}; App.Presenters.TagListPresenter = function( + _, jQuery, + util, + promise, + pagerPresenter, topNavigationPresenter) { var $el = jQuery('#content'); + var templates = {}; function init(args, loaded) { topNavigationPresenter.select('tags'); topNavigationPresenter.changeTitle('Tags'); - render(); + + promise.wait( + util.promiseTemplate('tag-list'), + util.promiseTemplate('tag-list-item')) + .then(function(listTemplate, listItemTemplate) { + templates.list = listTemplate; + templates.listItem = listItemTemplate; + + render(); + loaded(); + + pagerPresenter.init({ + baseUri: '#/tags', + backendUri: '/tags', + $target: $el.find('.pagination-target'), + updateCallback: function(data, clear) { + renderTags(data.entities, clear); + }, + }, + function() { + reinit(args, function() {}); + }); + }); + } + + function reinit(args, loaded) { loaded(); + + var searchArgs = util.parseComplexRouteArgs(args.searchArgs); + searchArgs.order = searchArgs.order || 'name,asc'; + searchArgs.page = parseInt(searchArgs.page) || 1; + updateActiveOrder(searchArgs.order); + + pagerPresenter.reinit({ + page: searchArgs.page, + searchParams: { + order: searchArgs.order}}); + } + + function deinit() { + pagerPresenter.deinit(); } function render() { - $el.html('Tag list placeholder'); + $el.html(templates.list()); + } + + function updateActiveOrder(activeOrder) { + $el.find('.order li a').removeClass('active'); + $el.find('.order [href*="' + activeOrder + '"]').addClass('active'); + } + + function renderTags(tags, clear) { + var $target = $el.find('.tags'); + + if (clear) { + $target.empty(); + } + + _.each(tags, function(tag) { + var $item = jQuery(templates.listItem({ + tag: tag, + formatRelativeTime: util.formatRelativeTime, + })); + $target.append($item); + }); } return { init: init, + reinit: reinit, + deinit: deinit, render: render, }; }; -App.DI.register('tagListPresenter', ['jQuery', 'topNavigationPresenter'], App.Presenters.TagListPresenter); +App.DI.register('tagListPresenter', ['_', 'jQuery', 'util', 'promise', 'pagerPresenter', 'topNavigationPresenter'], App.Presenters.TagListPresenter); diff --git a/public_html/js/Presenters/UserPresenter.js b/public_html/js/Presenters/UserPresenter.js index 4035d933..e4593138 100644 --- a/public_html/js/Presenters/UserPresenter.js +++ b/public_html/js/Presenters/UserPresenter.js @@ -24,7 +24,7 @@ App.Presenters.UserPresenter = function( function init(args, loaded) { promise.wait(util.promiseTemplate('user')) - .then(function(template, response) { + .then(function(template) { $messages = $el.find('.messages'); templates.user = template; reinit(args, loaded); diff --git a/public_html/templates/tag-list-item.tpl b/public_html/templates/tag-list-item.tpl new file mode 100644 index 00000000..c9238ea8 --- /dev/null +++ b/public_html/templates/tag-list-item.tpl @@ -0,0 +1,5 @@ + + + <%= tag.name %> (<%= tag.usages %>) + + diff --git a/public_html/templates/tag-list.tpl b/public_html/templates/tag-list.tpl new file mode 100644 index 00000000..6fac8002 --- /dev/null +++ b/public_html/templates/tag-list.tpl @@ -0,0 +1,18 @@ +
+ + +
+ +
+
+
diff --git a/src/Controllers/TagController.php b/src/Controllers/TagController.php new file mode 100644 index 00000000..0ab5a4f9 --- /dev/null +++ b/src/Controllers/TagController.php @@ -0,0 +1,45 @@ +privilegeService = $privilegeService; + $this->tagService = $tagService; + $this->tagViewProxy = $tagViewProxy; + $this->tagSearchParser = $tagSearchParser; + $this->inputReader = $inputReader; + } + + public function registerRoutes(\Szurubooru\Router $router) + { + $router->get('/api/tags', [$this, 'getTags']); + } + + public function getTags() + { + $this->privilegeService->assertPrivilege(\Szurubooru\Privilege::LIST_TAGS); + + $filter = $this->tagSearchParser->createFilterFromInputReader($this->inputReader); + $filter->setPageSize(50); + + $result = $this->tagService->getFiltered($filter); + $entities = $this->tagViewProxy->fromArray($result->getEntities()); + return [ + 'data' => $entities, + 'pageSize' => $result->getPageSize(), + 'totalRecords' => $result->getTotalRecords()]; + } +} diff --git a/src/SearchServices/Filters/TagFilter.php b/src/SearchServices/Filters/TagFilter.php new file mode 100644 index 00000000..e05402cf --- /dev/null +++ b/src/SearchServices/Filters/TagFilter.php @@ -0,0 +1,15 @@ +setOrder([self::ORDER_ID => self::ORDER_DESC]); + } +} diff --git a/src/SearchServices/Parsers/TagSearchParser.php b/src/SearchServices/Parsers/TagSearchParser.php new file mode 100644 index 00000000..e24205f6 --- /dev/null +++ b/src/SearchServices/Parsers/TagSearchParser.php @@ -0,0 +1,37 @@ +timeService = $timeService; } + public function getFiltered(\Szurubooru\SearchServices\Filters\TagFilter $filter) + { + $transactionFunc = function() use ($filter) + { + return $this->tagDao->findFiltered($filter); + }; + return $this->transactionManager->rollback($transactionFunc); + } + public function createTags(array $tags) { $transactionFunc = function() use ($tags) diff --git a/src/di.php b/src/di.php index 740f0b6e..1eadc921 100644 --- a/src/di.php +++ b/src/di.php @@ -49,6 +49,7 @@ return [ $container->get(\Szurubooru\Controllers\FavoritesController::class), $container->get(\Szurubooru\Controllers\ScoreController::class), $container->get(\Szurubooru\Controllers\CommentController::class), + $container->get(\Szurubooru\Controllers\TagController::class), ]; }), ];