From 91d52bcfcfb33abd0a0c3b1d59efc9f03965a89f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Andrej=20Rama=C5=A1euski?= <andrej@x2.cz>
Date: Wed, 30 Nov 2022 22:28:47 +0100
Subject: [PATCH] Pokrocilejsi seznam osob

---
 VERSION                                    |  2 +-
 lib/SeMeet/Controller/Groups.pm            |  2 +-
 lib/SeMeet/Controller/Users.pm             | 69 ++++++++++++++++++++++
 openapi.yaml                               | 39 ++++++++++--
 templates/includes/meet_moderators.html.ep |  2 +-
 templates/meet.html.ep                     |  5 +-
 6 files changed, 110 insertions(+), 9 deletions(-)
 create mode 100644 lib/SeMeet/Controller/Users.pm

diff --git a/VERSION b/VERSION
index 1d0ba9e..8f0916f 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.4.0
+0.5.0
diff --git a/lib/SeMeet/Controller/Groups.pm b/lib/SeMeet/Controller/Groups.pm
index 789a030..a98755d 100644
--- a/lib/SeMeet/Controller/Groups.pm
+++ b/lib/SeMeet/Controller/Groups.pm
@@ -14,7 +14,7 @@ sub list($c) {
     );
 
     my @groups = ();
-# TODO: filter
+
     GROUP:
     while ( my $group = $groups->next()) {
         push @groups, $c->spec_filter({
diff --git a/lib/SeMeet/Controller/Users.pm b/lib/SeMeet/Controller/Users.pm
new file mode 100644
index 0000000..e3ea8df
--- /dev/null
+++ b/lib/SeMeet/Controller/Users.pm
@@ -0,0 +1,69 @@
+package SeMeet::Controller::Users;
+use Mojo::Base 'Mojolicious::Controller', -signatures;
+
+use utf8;
+use JSON;
+use constant REDIS_CACHE_LIFETIME => 60;
+
+sub list($c) {
+    $c->openapi->valid_input or return;
+    my $args = $c->validation->output;
+
+    my $cache_key = sprintf('USERS %s', $args->{search} || 'ALL');
+    if ($c->redis->db->exists( $cache_key )) {
+        $c->render(openapi => from_json($c->redis->db->get( $cache_key )));
+        return;
+    }
+
+    my $groups = $c->schema->resultset('Group')->search(
+        { permissions => { ilike => 'org-%' }}, # TODO: samostatny priznak?
+        { order_by => 'name', }
+    );
+
+    my %groups = ();
+
+    GROUP:
+    while ( my $group = $groups->next()) {
+        my $name = $group->name;
+
+        next GROUP if $name !~ s/^(KS|MS)\s+//i;
+
+        my $type = $1;
+
+        $name =~ s/\s+členové a RegP//i;
+        $groups{$type}->{$group->octid} = $name;
+    }
+
+    my $users = $c->iapi->get('octopus/users?search=' . $args->{search});
+
+    my @users = ();
+
+    USER:
+    foreach my $user ( @{ $users } ) {
+
+        my ($ks, $ms);
+
+        GROUP:
+        foreach my $id (@{ $user->{groups} }) {
+            if ( my $group = $groups{KS}->{$id} ) {
+                $ks //= $group;
+            }
+            if ( my $group = $groups{MS}->{$id} ) {
+                $ms //= $group;
+            }
+        }
+
+        push @users, $c->spec_filter({
+            id          => $user->{id},
+            name        => $user->{displayname},
+            username    => $user->{username},
+            region      => join ' - ', grep { defined } ($ks, $ms),
+        }, 'UserInList')
+    }
+
+    $c->redis->db->set( $cache_key, to_json(\@users), 'EX', REDIS_CACHE_LIFETIME );
+    $c->render( openapi => \@users );
+}
+
+1;
+
diff --git a/openapi.yaml b/openapi.yaml
index ee4791b..5672914 100644
--- a/openapi.yaml
+++ b/openapi.yaml
@@ -66,6 +66,14 @@ components:
         name:
           type: string
           readOnly: true
+        username:
+          type: string
+          readOnly: true
+          nullable: true
+        region:
+          type: string
+          nullable: true
+          readOnly: true
 
 paths:
   /meets:
@@ -216,14 +224,13 @@ paths:
         204:
           description: Mistnost je smazana
 
-  /meets/{id}/unauthorized_groups:
+  /groups:
     get:
       x-mojo-to: groups#list
       tags:
-        - meets
         - groups
-      summary: "Seznam nezarazenych skupin"
-      operationId: searchUnauthorizeGroups
+      summary: "Hledani skupin"
+      operationId: searchGroups
       parameters:
       - name: search
         in: query
@@ -241,6 +248,30 @@ paths:
                 items:
                   $ref: '#/components/schemas/GroupInList'
 
+  /users:
+    get:
+      x-mojo-to: users#list
+      tags:
+        - users
+      summary: "Hledani osob"
+      operationId: searchUsers
+      parameters:
+      - name: search
+        in: query
+        description: Search query
+        schema:
+          type: string
+          example: 'Ivan'
+      responses:
+        200:
+          description: Seznam osob
+          content:
+            application/json:
+              schema:
+                type: array
+                items:
+                  $ref: '#/components/schemas/UserInList'
+
   /meets/{id}/group:
     post:
       x-mojo-to: meets#add_groups
diff --git a/templates/includes/meet_moderators.html.ep b/templates/includes/meet_moderators.html.ep
index a6ed190..2b637bb 100644
--- a/templates/includes/meet_moderators.html.ep
+++ b/templates/includes/meet_moderators.html.ep
@@ -16,7 +16,7 @@
     <div class="overflow-y-auto h-64 mb-4 border p-2 text-sm" v-if="users.length > 0">
     <div v-for="user in users" class="checkbox form-field__control mb-1" >
      <input name="users" type="checkbox" v-bind:title="user.id" v-bind:value="user.id"  v-model="selected_users" >
-     <label>{{user.name}}</label>
+     <label style="max-width: 100%">{{user.name}} ({{ user.username }})<span v-if="user.region.length > 0" class="text-grey-300 text-xs"> | {{ user.region }}</span></label>
     </div>
     </div>
     <div class="form-field" v-if="selected_users.length > 0">
diff --git a/templates/meet.html.ep b/templates/meet.html.ep
index 2186586..d9904a9 100644
--- a/templates/meet.html.ep
+++ b/templates/meet.html.ep
@@ -31,8 +31,9 @@
 <script type="module">
   import { createApp } from 'https://cdn-unpkg.pirati.cz/petite-vue@0.2.2/dist/petite-vue.es.js'
 
-  const GROUPS_URL      = '/api/meets/<%= stash->{id} %>/unauthorized_groups';
-  const USERS_URL       = '<%= config->{iapi} %>octopus/users';
+  const GROUPS_URL      = '/api/groups';
+  const USERS_URL       = '/api/users';
+//const USERS_URL       = '<%= config->{iapi} %>octopus/users';
   const MEET_URL        = '/api/meets/<%= stash->{id} %>';
   const ADD_GROUPS_URL  = '/api/meets/<%= stash->{id} %>/group';
   const ADD_USERS_URL   = '/api/meets/<%= stash->{id} %>/moderator';
-- 
GitLab