diff --git a/config/router.js b/config/router.js index fef3fd4..6db7bec 100644 --- a/config/router.js +++ b/config/router.js @@ -151,6 +151,7 @@ module.exports = router => { ); extended.get('/api/users', controller.users.get_users); + extended.get('/api/user_auto_complete', $.permission_or_role_manager, controller.users.get_user_from_autocomplete); /** * Roles routes diff --git a/controllers/users.js b/controllers/users.js index 76528ea..8a62701 100644 --- a/controllers/users.js +++ b/controllers/users.js @@ -11,6 +11,7 @@ const { module.exports = { get_users, + get_user_from_autocomplete, }; async function get_users(req) { @@ -44,3 +45,29 @@ async function get_users(req) { data }; } +async function get_user_from_autocomplete(req) { + const input = { + ...req.query, + ...req.params + }; + + const rules = { + autocomplete: 'required|object', + }; + + let validated_input = await indicative.validate(input, rules); + + const user_factory = factory.create(USERS); + const users = await user_factory.get_users_test(validated_input); + + const data = { + items: users, + total: users.length, + ..._.pick(validated_input, ['page', 'per_page']) + }; + + return { + ...responses.FETCH_USER_SUGGESTIONS_SUCCESS, + data + }; +} diff --git a/helpers/util.js b/helpers/util.js index 1682e2c..dde7c21 100644 --- a/helpers/util.js +++ b/helpers/util.js @@ -281,6 +281,25 @@ function get_managed_role_names(user_managed_permissions) { return managed_role_names; } +function get_match_type_string(match_type = null, search_query) { + let match_type_string = ''; + switch (match_type) { + case 'any': + match_type_string = `%${search_query}%`; + break; + case 'start': + match_type_string = `${search_query}%`; + break; + case 'end': + match_type_string = `%${search_query}`; + break; + default: + match_type_string = search_query; + break; + } + + return match_type_string; +} module.exports = { hash, @@ -304,4 +323,5 @@ module.exports = { merge_by_key, markdown_to_html, get_managed_role_names, + get_match_type_string, }; diff --git a/repositories/users.js b/repositories/users.js index 8830f34..c517d5f 100644 --- a/repositories/users.js +++ b/repositories/users.js @@ -4,6 +4,7 @@ const _ = require('lodash'); const squel = require('squel').useFlavour('mysql'); const config = require('config/config'); const base_repository = require('repositories/base_repository'); +const util = require('helpers/util'); const YTFREEDOM_DB = config.DATABASE.YTFREEDOM.database; const { ASSIGNED_ROLES, @@ -138,6 +139,47 @@ class users extends base_repository { return this.run_query(); } + get_query_test(options) { + let fields = [ + 'u.id', + 'u.name', + 'u.username', + 'u.picture as avatar', + ]; + + this.select(fields) + .where('u.deleted_at IS NULL'); + + const option_fields = _.get(options, 'autocomplete.fields'); + let search_string = _.get(options, 'autocomplete.search_string'); + const expr = squel.expr(); + _.forEach(_.keys(option_fields), (field) => { + const option = _.get(option_fields, field); + if(option.operation === 'like') { + expr.or(`${field} ${option.operation} ?`, util.get_match_type_string(option.match_type, search_string)); + } else { + expr.or(`${field} ${option.operation} ?`, search_string); + } + }); + this.where(expr); + + return this._query; + } + + get_users_test(options) { + this.get_query_test(options); + + if (options.sort_by) { + this.order( + _.get(options, 'sort_by'), + true + ); + } + this.limit(config.PAGINATION_DEFAULTS.per_page) + .offset(config.PAGINATION_DEFAULTS.per_page * (config.PAGINATION_DEFAULTS.page - 1)); + + return this.run_query(); + } }