diff options
author | Thomas Citharel <tcit@tcit.fr> | 2017-04-27 15:58:32 +0200 |
---|---|---|
committer | Nicolas Lœuillet <nicolas@loeuillet.org> | 2017-05-02 15:28:39 +0200 |
commit | c37515f880bd05b86e3e848cc184018295ec1920 (patch) | |
tree | c64785ee1bce798fe05d6b06e63abff0a41ffcea | |
parent | e1d64050ad6f54e45d3954ffac21daaee58c6240 (diff) | |
download | wallabag-c37515f880bd05b86e3e848cc184018295ec1920.tar.gz wallabag-c37515f880bd05b86e3e848cc184018295ec1920.tar.zst wallabag-c37515f880bd05b86e3e848cc184018295ec1920.zip |
Add filter to users management page
Signed-off-by: Thomas Citharel <tcit@tcit.fr>
17 files changed, 170 insertions, 28 deletions
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml index 72493fe3..68fcec5c 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.da.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | # delete: Delete | 512 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 513 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 514 | # back_to_list: Back to list |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml index dbad8b16..be117231 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.de.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: Löschen | 512 | delete: Löschen |
513 | delete_confirm: Bist du sicher? | 513 | delete_confirm: Bist du sicher? |
514 | back_to_list: Zurück zur Liste | 514 | back_to_list: Zurück zur Liste |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Ein Fehler ist aufgetreten | 520 | page_title: Ein Fehler ist aufgetreten |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml index 42a12b2a..b3850893 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.en.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: Delete | 512 | delete: Delete |
513 | delete_confirm: Are you sure? | 513 | delete_confirm: Are you sure? |
514 | back_to_list: Back to list | 514 | back_to_list: Back to list |
515 | search: | ||
516 | label: Filter | ||
517 | placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: An error occurred | 520 | page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml index 6e21614e..ebf6745a 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.es.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: Eliminar | 512 | delete: Eliminar |
513 | delete_confirm: ¿Estás seguro? | 513 | delete_confirm: ¿Estás seguro? |
514 | back_to_list: Volver a la lista | 514 | back_to_list: Volver a la lista |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Ha ocurrido un error | 520 | page_title: Ha ocurrido un error |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml index b938c80a..46460e13 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fa.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | # delete: Delete | 512 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 513 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 514 | # back_to_list: Back to list |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml index 9abcda45..c968f7ab 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.fr.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: "Supprimer" | 512 | delete: "Supprimer" |
513 | delete_confirm: "Voulez-vous vraiment ?" | 513 | delete_confirm: "Voulez-vous vraiment ?" |
514 | back_to_list: "Revenir à la liste" | 514 | back_to_list: "Revenir à la liste" |
515 | search: | ||
516 | label: Filtrer | ||
517 | placeholder: Filtrer par nom d'utilisateur ou email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Une erreur est survenue | 520 | page_title: Une erreur est survenue |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml index 58d0962a..53b5e1b9 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.it.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | # delete: Delete | 512 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 513 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 514 | # back_to_list: Back to list |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml index 825a0efd..c6614a63 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.oc.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: 'Suprimir' | 512 | delete: 'Suprimir' |
513 | delete_confirm: 'Sètz segur ?' | 513 | delete_confirm: 'Sètz segur ?' |
514 | back_to_list: 'Tornar a la lista' | 514 | back_to_list: 'Tornar a la lista' |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Una error s'es produsida | 520 | page_title: Una error s'es produsida |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml index b02aa4ec..b464d0f6 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pl.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: Usuń | 512 | delete: Usuń |
513 | delete_confirm: Jesteś pewien? | 513 | delete_confirm: Jesteś pewien? |
514 | back_to_list: Powrót do listy | 514 | back_to_list: Powrót do listy |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | page_title: Wystąpił błąd | 520 | page_title: Wystąpił błąd |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml index 8aa7e5af..2b0b1686 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.pt.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | delete: 'Apagar' | 512 | delete: 'Apagar' |
513 | delete_confirm: 'Tem certeza?' | 513 | delete_confirm: 'Tem certeza?' |
514 | back_to_list: 'Voltar para a lista' | 514 | back_to_list: 'Voltar para a lista' |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml index ce8d8d52..210978d0 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.ro.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | # delete: Delete | 512 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 513 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 514 | # back_to_list: Back to list |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml index d8903608..5ff5e012 100644 --- a/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml +++ b/src/Wallabag/CoreBundle/Resources/translations/messages.tr.yml | |||
@@ -512,6 +512,9 @@ user: | |||
512 | # delete: Delete | 512 | # delete: Delete |
513 | # delete_confirm: Are you sure? | 513 | # delete_confirm: Are you sure? |
514 | # back_to_list: Back to list | 514 | # back_to_list: Back to list |
515 | search: | ||
516 | # label: Filter | ||
517 | # placeholder: Filter by username or email | ||
515 | 518 | ||
516 | error: | 519 | error: |
517 | # page_title: An error occurred | 520 | # page_title: An error occurred |
diff --git a/src/Wallabag/UserBundle/Controller/ManageController.php b/src/Wallabag/UserBundle/Controller/ManageController.php index 92ee2b41..f0e3d4de 100644 --- a/src/Wallabag/UserBundle/Controller/ManageController.php +++ b/src/Wallabag/UserBundle/Controller/ManageController.php | |||
@@ -10,6 +10,7 @@ use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; | |||
10 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; | 10 | use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; |
11 | use Wallabag\UserBundle\Entity\User; | 11 | use Wallabag\UserBundle\Entity\User; |
12 | use Wallabag\CoreBundle\Entity\Config; | 12 | use Wallabag\CoreBundle\Entity\Config; |
13 | use Wallabag\UserBundle\Form\SearchUserType; | ||
13 | 14 | ||
14 | /** | 15 | /** |
15 | * User controller. | 16 | * User controller. |
@@ -146,4 +147,45 @@ class ManageController extends Controller | |||
146 | ->getForm() | 147 | ->getForm() |
147 | ; | 148 | ; |
148 | } | 149 | } |
150 | |||
151 | /** | ||
152 | * @param Request $request | ||
153 | * @param int $page | ||
154 | * | ||
155 | * @Route("/search/{page}", name="user-search", defaults={"page" = 1}) | ||
156 | * | ||
157 | * Default parameter for page is hardcoded (in duplication of the defaults from the Route) | ||
158 | * because this controller is also called inside the layout template without any page as argument | ||
159 | * | ||
160 | * @return \Symfony\Component\HttpFoundation\Response | ||
161 | */ | ||
162 | public function searchFormAction(Request $request, $page = 1, $currentRoute = null) | ||
163 | { | ||
164 | // fallback to retrieve currentRoute from query parameter instead of injected one (when using inside a template) | ||
165 | if (null === $currentRoute && $request->query->has('currentRoute')) { | ||
166 | $currentRoute = $request->query->get('currentRoute'); | ||
167 | } | ||
168 | |||
169 | $form = $this->createForm(SearchUserType::class); | ||
170 | |||
171 | $form->handleRequest($request); | ||
172 | |||
173 | if ($form->isSubmitted() && $form->isValid()) { | ||
174 | $this->get('logger')->info('searching users'); | ||
175 | $em = $this->getDoctrine()->getManager(); | ||
176 | |||
177 | $searchTerm = (isset($request->get('search_user')['term']) ? $request->get('search_user')['term'] : ''); | ||
178 | |||
179 | $users = $em->getRepository('WallabagUserBundle:User')->getUsersForSearch($searchTerm); | ||
180 | |||
181 | return $this->render('WallabagUserBundle:Manage:index.html.twig', array( | ||
182 | 'users' => $users, | ||
183 | )); | ||
184 | } | ||
185 | |||
186 | return $this->render('WallabagUserBundle:Manage:search_form.html.twig', [ | ||
187 | 'form' => $form->createView(), | ||
188 | 'currentRoute' => $currentRoute, | ||
189 | ]); | ||
190 | } | ||
149 | } | 191 | } |
diff --git a/src/Wallabag/UserBundle/Form/SearchUserType.php b/src/Wallabag/UserBundle/Form/SearchUserType.php new file mode 100644 index 00000000..9ce46ee1 --- /dev/null +++ b/src/Wallabag/UserBundle/Form/SearchUserType.php | |||
@@ -0,0 +1,29 @@ | |||
1 | <?php | ||
2 | |||
3 | namespace Wallabag\UserBundle\Form; | ||
4 | |||
5 | use Symfony\Component\Form\AbstractType; | ||
6 | use Symfony\Component\Form\Extension\Core\Type\TextType; | ||
7 | use Symfony\Component\Form\FormBuilderInterface; | ||
8 | use Symfony\Component\OptionsResolver\OptionsResolver; | ||
9 | |||
10 | class SearchUserType extends AbstractType | ||
11 | { | ||
12 | public function buildForm(FormBuilderInterface $builder, array $options) | ||
13 | { | ||
14 | $builder | ||
15 | ->setMethod('GET') | ||
16 | ->add('term', TextType::class, [ | ||
17 | 'required' => true, | ||
18 | 'label' => 'user.new.form_search.term_label', | ||
19 | ]) | ||
20 | ; | ||
21 | } | ||
22 | |||
23 | public function configureOptions(OptionsResolver $resolver) | ||
24 | { | ||
25 | $resolver->setDefaults([ | ||
26 | 'csrf_protection' => false, | ||
27 | ]); | ||
28 | } | ||
29 | } | ||
diff --git a/src/Wallabag/UserBundle/Repository/UserRepository.php b/src/Wallabag/UserBundle/Repository/UserRepository.php index f913f52d..66bbab39 100644 --- a/src/Wallabag/UserBundle/Repository/UserRepository.php +++ b/src/Wallabag/UserBundle/Repository/UserRepository.php | |||
@@ -52,4 +52,19 @@ class UserRepository extends EntityRepository | |||
52 | ->getQuery() | 52 | ->getQuery() |
53 | ->getSingleScalarResult(); | 53 | ->getSingleScalarResult(); |
54 | } | 54 | } |
55 | |||
56 | /** | ||
57 | * Retrieves users filtered with a search term. | ||
58 | * | ||
59 | * @param string $term | ||
60 | * | ||
61 | * @return QueryBuilder | ||
62 | */ | ||
63 | public function getUsersForSearch($term) | ||
64 | { | ||
65 | return $this->createQueryBuilder('u') | ||
66 | ->andWhere('lower(u.username) LIKE lower(:term) OR lower(u.email) LIKE lower(:term) OR lower(u.name) LIKE lower(:term)')->setParameter('term', '%'.$term.'%') | ||
67 | ->getQuery() | ||
68 | ->getResult(); | ||
69 | } | ||
55 | } | 70 | } |
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig index daba29e4..abc02852 100644 --- a/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig +++ b/src/Wallabag/UserBundle/Resources/views/Manage/index.html.twig | |||
@@ -8,36 +8,41 @@ | |||
8 | <div class="col s12"> | 8 | <div class="col s12"> |
9 | <div class="card-panel"> | 9 | <div class="card-panel"> |
10 | <div class="row"> | 10 | <div class="row"> |
11 | <div class="input-field col s12"> | 11 | <div class="col s6"> |
12 | <p class="help">{{ 'user.description'|trans|raw }}</p> | 12 | <p class="help">{{ 'user.description'|trans|raw }}</p> |
13 | |||
14 | <table class="bordered"> | ||
15 | <thead> | ||
16 | <tr> | ||
17 | <th>{{ 'user.form.username_label'|trans }}</th> | ||
18 | <th>{{ 'user.form.email_label'|trans }}</th> | ||
19 | <th>{{ 'user.form.last_login_label'|trans }}</th> | ||
20 | <th>{{ 'user.list.actions'|trans }}</th> | ||
21 | </tr> | ||
22 | </thead> | ||
23 | <tbody> | ||
24 | {% for user in users %} | ||
25 | <tr> | ||
26 | <td>{{ user.username }}</td> | ||
27 | <td>{{ user.email }}</td> | ||
28 | <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td> | ||
29 | <td> | ||
30 | <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a> | ||
31 | </td> | ||
32 | </tr> | ||
33 | {% endfor %} | ||
34 | </tbody> | ||
35 | </table> | ||
36 | <br /> | ||
37 | <p> | ||
38 | <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a> | ||
39 | </p> | ||
40 | </div> | 13 | </div> |
14 | <div class="col s6"> | ||
15 | <div class="input-field"> | ||
16 | {{ render(controller("WallabagUserBundle:Manage:searchForm", {'currentRoute': app.request.attributes.get('_route')})) }} | ||
17 | </div> | ||
18 | </div> | ||
19 | |||
20 | <table class="bordered"> | ||
21 | <thead> | ||
22 | <tr> | ||
23 | <th>{{ 'user.form.username_label'|trans }}</th> | ||
24 | <th>{{ 'user.form.email_label'|trans }}</th> | ||
25 | <th>{{ 'user.form2017-03-10 16:51:07.last_login_label'|trans }}</th> | ||
26 | <th>{{ 'user.list.actions'|trans }}</th> | ||
27 | </tr> | ||
28 | </thead> | ||
29 | <tbody> | ||
30 | {% for user in users %} | ||
31 | <tr> | ||
32 | <td>{{ user.username }}</td> | ||
33 | <td>{{ user.email }}</td> | ||
34 | <td>{% if user.lastLogin %}{{ user.lastLogin|date('Y-m-d H:i:s') }}{% endif %}</td> | ||
35 | <td> | ||
36 | <a href="{{ path('user_edit', { 'id': user.id }) }}">{{ 'user.list.edit_action'|trans }}</a> | ||
37 | </td> | ||
38 | </tr> | ||
39 | {% endfor %} | ||
40 | </tbody> | ||
41 | </table> | ||
42 | <br /> | ||
43 | <p> | ||
44 | <a href="{{ path('user_new') }}" class="waves-effect waves-light btn">{{ 'user.list.create_new_one'|trans }}</a> | ||
45 | </p> | ||
41 | </div> | 46 | </div> |
42 | </div> | 47 | </div> |
43 | </div> | 48 | </div> |
diff --git a/src/Wallabag/UserBundle/Resources/views/Manage/search_form.html.twig b/src/Wallabag/UserBundle/Resources/views/Manage/search_form.html.twig new file mode 100644 index 00000000..f59388d0 --- /dev/null +++ b/src/Wallabag/UserBundle/Resources/views/Manage/search_form.html.twig | |||
@@ -0,0 +1,15 @@ | |||
1 | <form name="search" method="GET" action="{{ path('user-search')}}"> | ||
2 | {% if form_errors(form) %} | ||
3 | <span class="black-text">{{ form_errors(form) }}</span> | ||
4 | {% endif %} | ||
5 | |||
6 | {% if form_errors(form.term) %} | ||
7 | <span class="black-text">{{ form_errors(form.term) }}</span> | ||
8 | {% endif %} | ||
9 | |||
10 | <i class="material-icons prefix">search</i> | ||
11 | {{ form_widget(form.term, { 'attr': {'autocomplete': 'off', 'placeholder': 'user.search.placeholder'} }) }} | ||
12 | <label for="search_user_term" class="active">{{ 'user.search.label' | trans }}</label> | ||
13 | |||
14 | {{ form_rest(form) }} | ||
15 | </form> | ||