1
0
mirror of https://github.com/LaCasemate/fab-manager.git synced 2025-02-21 15:54:22 +01:00

Merge branch 'users' into dev

This commit is contained in:
Sylvain 2016-06-16 12:55:29 +02:00
commit a358ef7dbc
6 changed files with 42 additions and 39 deletions

View File

@ -595,8 +595,8 @@ Go to your projects gallery and enjoy seeing your projects available from everyw
- Using another DBMS than PostgreSQL is not supported, because of some PostgreSQL specific instructions: - Using another DBMS than PostgreSQL is not supported, because of some PostgreSQL specific instructions:
- `app/controllers/api/members_controllers.rb@list` is using `ILIKE` - `app/controllers/api/members_controllers.rb@list` is using `ILIKE`
- `app/controllers/api/invoices_controllers.rb@list` is using `ILIKE` and `date_trunc()` - `app/controllers/api/invoices_controllers.rb@list` is using `ILIKE` and `date_trunc()`
- `db/migrate/20160613093842_create_unaccent_function.rb` is using [unaccent](https://www.postgresql.org/docs/current/static/unaccent.html) and [trigram](https://www.postgresql.org/docs/current/static/pgtrgm.html) modules - `db/migrate/20160613093842_create_unaccent_function.rb` is using [unaccent](https://www.postgresql.org/docs/current/static/unaccent.html) and [trigram](https://www.postgresql.org/docs/current/static/pgtrgm.html) modules and defines a PL/pgSQL function (`f_unaccent()`)
- `app/controllers/api/members_controllers.rb@search` is using `f_unaccent()` defined in the migration above - `app/controllers/api/members_controllers.rb@search` is using `f_unaccent()` (see above) and `regexp_replace()`
<a name="related-documentation"></a> <a name="related-documentation"></a>
## Related Documentation ## Related Documentation

View File

@ -24,7 +24,7 @@
# - $state (Ui-Router) [ 'app.public.projects_show', 'app.public.projects_list' ] # - $state (Ui-Router) [ 'app.public.projects_show', 'app.public.projects_list' ]
## ##
class ProjectsController class ProjectsController
constructor: ($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document)-> constructor: ($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics)->
## Retrieve the list of machines from the server ## Retrieve the list of machines from the server
Machine.query().$promise.then (data)-> Machine.query().$promise.then (data)->
@ -140,6 +140,17 @@ class ProjectsController
$scope.project.project_steps_attributes.splice(index, 1) $scope.project.project_steps_attributes.splice(index, 1)
$scope.autoCompleteName = (nameLookup) ->
unless nameLookup
return
asciiName = Diacritics.remove(nameLookup)
Member.search { query: asciiName }, (users) ->
$scope.matchingMembers = users
, (error)->
console.error(error)
## ##
# Controller used on projects listing page # Controller used on projects listing page
@ -275,8 +286,8 @@ Application.Controllers.controller "ProjectsController", ["$scope", "$state", 'P
## ##
# Controller used in the project creation page # Controller used in the project creation page
## ##
Application.Controllers.controller "NewProjectController", ["$scope", "$state", 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF' Application.Controllers.controller "NewProjectController", ["$scope", "$state", 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'Diacritics'
, ($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, CSRF) -> , ($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, Diacritics) ->
CSRF.setMetaTags() CSRF.setMetaTags()
## API URL where the form will be posted ## API URL where the form will be posted
@ -290,16 +301,10 @@ Application.Controllers.controller "NewProjectController", ["$scope", "$state",
project_steps_attributes: [] project_steps_attributes: []
project_caos_attributes: [] project_caos_attributes: []
## Other members list (project collaborators) $scope.matchingMembers = []
Member.query().$promise.then (data)->
$scope.members = data.filter (m) ->
m.id != $scope.currentUser.id
.map (d) ->
id: d.id
name: d.name
## Using the ProjectsController ## Using the ProjectsController
new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document) new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics)
] ]
@ -307,8 +312,8 @@ Application.Controllers.controller "NewProjectController", ["$scope", "$state",
## ##
# Controller used in the project edition page # Controller used in the project edition page
## ##
Application.Controllers.controller "EditProjectController", ["$scope", "$state", '$stateParams', 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'projectPromise' Application.Controllers.controller "EditProjectController", ["$scope", "$state", '$stateParams', 'Project', 'Machine', 'Member', 'Component', 'Theme', 'Licence', '$document', 'CSRF', 'projectPromise', 'Diacritics'
, ($scope, $state, $stateParams, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, projectPromise) -> , ($scope, $state, $stateParams, Project, Machine, Member, Component, Theme, Licence, $document, CSRF, projectPromise, Diacritics) ->
CSRF.setMetaTags() CSRF.setMetaTags()
## API URL where the form will be posted ## API URL where the form will be posted
@ -320,16 +325,12 @@ Application.Controllers.controller "EditProjectController", ["$scope", "$state",
## Retrieve the project's details, if an error occured, redirect the user to the projects list page ## Retrieve the project's details, if an error occured, redirect the user to the projects list page
$scope.project = projectPromise $scope.project = projectPromise
## Other members list (project collaborators) $scope.matchingMembers = $scope.project.project_users.map (u) ->
Member.query().$promise.then (data)-> id: u.id
$scope.members = data.filter (m) -> name: u.full_name
m.id != $scope.project.author_id
.map (d) ->
id: d.id
name: d.name
## Using the ProjectsController ## Using the ProjectsController
new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document) new ProjectsController($scope, $state, Project, Machine, Member, Component, Theme, Licence, $document, Diacritics)
] ]

View File

@ -171,7 +171,7 @@
<span ng-bind="$item.name"></span> <span ng-bind="$item.name"></span>
<input type="hidden" name="project[user_ids][]" value="{{$item.id}}" /> <input type="hidden" name="project[user_ids][]" value="{{$item.id}}" />
</ui-select-match> </ui-select-match>
<ui-select-choices repeat="m.id as m in (members | filter: $select.search)"> <ui-select-choices repeat="m.id as m in matchingMembers" refresh="autoCompleteName($select.search)" refresh-delay="300">
<span ng-bind-html="m.name | highlight: $select.search"></span> <span ng-bind-html="m.name | highlight: $select.search"></span>
</ui-select-choices> </ui-select-choices>
</ui-select> </ui-select>

View File

@ -180,7 +180,6 @@ class API::MembersController < API::ApiController
end end
def search def search
authorize User
if params[:subscription] if params[:subscription]
subscription = (params[:subscription] === 'true') subscription = (params[:subscription] === 'true')
@ -189,13 +188,19 @@ class API::MembersController < API::ApiController
@members = User.includes(:profile) @members = User.includes(:profile)
.joins(:profile, :roles, 'LEFT JOIN "subscriptions" ON "subscriptions"."user_id" = "users"."id"') .joins(:profile, :roles, 'LEFT JOIN "subscriptions" ON "subscriptions"."user_id" = "users"."id"')
.where("users.is_active = 'true' AND roles.name = 'member'") .where("users.is_active = 'true' AND roles.name = 'member'")
.where("lower(f_unaccent(profiles.first_name)) LIKE ('%' || lower(f_unaccent(:search)) || '%') OR lower(f_unaccent(profiles.last_name)) LIKE ('%' || lower(f_unaccent(:search)) || '%')", search: params[:query]) .where("lower(f_unaccent(profiles.first_name)) ~ regexp_replace(:search, E'\\\\s+', '|') OR lower(f_unaccent(profiles.last_name)) ~ regexp_replace(:search, E'\\\\s+', '|')", search: params[:query].downcase)
if current_user.is_member?
# non-admin can only retrieve users with "public profiles"
@members = @members.where("users.is_allow_contact = 'true'")
else
# only admins have the ability to filter by subscription
if params[:subscription] === 'true' if params[:subscription] === 'true'
@members = @members.where('subscriptions.id IS NOT NULL AND subscriptions.expired_at >= :now', now: Date.today.to_s) @members = @members.where('subscriptions.id IS NOT NULL AND subscriptions.expired_at >= :now', now: Date.today.to_s)
elsif params[:subscription] === 'false' elsif params[:subscription] === 'false'
@members = @members.where('subscriptions.id IS NULL OR subscriptions.expired_at < :now', now: Date.today.to_s) @members = @members.where('subscriptions.id IS NULL OR subscriptions.expired_at < :now', now: Date.today.to_s)
end end
end
@members @members
end end

View File

@ -4,7 +4,7 @@ class UserPolicy < ApplicationPolicy
if user.is_admin? if user.is_admin?
scope.includes(:group, :training_credits, :machine_credits, :subscriptions => [:plan => [:credits]], :profile => [:user_avatar]).joins(:roles).where("users.is_active = 'true' AND roles.name = 'member'").order('users.created_at desc') scope.includes(:group, :training_credits, :machine_credits, :subscriptions => [:plan => [:credits]], :profile => [:user_avatar]).joins(:roles).where("users.is_active = 'true' AND roles.name = 'member'").order('users.created_at desc')
else else
scope.includes(:group, :training_credits, :machine_credits, :profile => [:user_avatar]).joins(:roles).where("users.is_active = 'true' AND roles.name = 'member'").where(is_allow_contact: true).order('users.created_at desc') scope.includes(:profile => [:user_avatar]).joins(:roles).where("users.is_active = 'true' AND roles.name = 'member'").where(is_allow_contact: true).order('users.created_at desc')
end end
end end
end end
@ -33,7 +33,4 @@ class UserPolicy < ApplicationPolicy
user.is_admin? user.is_admin?
end end
def search?
user.is_admin?
end
end end

View File

@ -227,7 +227,7 @@ ActiveRecord::Schema.define(version: 20160613093842) do
t.boolean "is_read", default: false t.boolean "is_read", default: false
t.datetime "created_at" t.datetime "created_at"
t.datetime "updated_at" t.datetime "updated_at"
t.string "receiver_type" t.string "receiver_type", limit: 255
t.boolean "is_send", default: false t.boolean "is_send", default: false
t.jsonb "meta_data", default: {} t.jsonb "meta_data", default: {}
end end
@ -368,7 +368,7 @@ ActiveRecord::Schema.define(version: 20160613093842) do
t.datetime "published_at" t.datetime "published_at"
end end
add_index "projects", ["slug"], name: "index_projects_on_slug", using: :btree add_index "projects", ["slug"], name: "index_projects_on_slug", unique: true, using: :btree
create_table "projects_components", force: :cascade do |t| create_table "projects_components", force: :cascade do |t|
t.integer "project_id" t.integer "project_id"
@ -438,8 +438,8 @@ ActiveRecord::Schema.define(version: 20160613093842) do
t.datetime "updated_at" t.datetime "updated_at"
t.integer "availability_id" t.integer "availability_id"
t.datetime "ex_start_at" t.datetime "ex_start_at"
t.datetime "ex_end_at"
t.datetime "canceled_at" t.datetime "canceled_at"
t.datetime "ex_end_at"
t.boolean "offered", default: false t.boolean "offered", default: false
end end
@ -597,6 +597,7 @@ ActiveRecord::Schema.define(version: 20160613093842) do
add_index "user_trainings", ["user_id"], name: "index_user_trainings_on_user_id", using: :btree add_index "user_trainings", ["user_id"], name: "index_user_trainings_on_user_id", using: :btree
create_table "users", force: :cascade do |t| create_table "users", force: :cascade do |t|
t.string "username", limit: 255
t.string "email", limit: 255, default: "", null: false t.string "email", limit: 255, default: "", null: false
t.string "encrypted_password", limit: 255, default: "", null: false t.string "encrypted_password", limit: 255, default: "", null: false
t.string "reset_password_token", limit: 255 t.string "reset_password_token", limit: 255
@ -619,7 +620,6 @@ ActiveRecord::Schema.define(version: 20160613093842) do
t.boolean "is_allow_contact", default: true t.boolean "is_allow_contact", default: true
t.integer "group_id" t.integer "group_id"
t.string "stp_customer_id", limit: 255 t.string "stp_customer_id", limit: 255
t.string "username", limit: 255
t.string "slug", limit: 255 t.string "slug", limit: 255
t.boolean "is_active", default: true t.boolean "is_active", default: true
t.boolean "invoicing_disabled", default: false t.boolean "invoicing_disabled", default: false