diff --git a/app/assets/javascripts/users/settings/teams.js b/app/assets/javascripts/users/settings/teams.js index 6e1008211..973457ecf 100644 --- a/app/assets/javascripts/users/settings/teams.js +++ b/app/assets/javascripts/users/settings/teams.js @@ -56,4 +56,38 @@ function initLeaveTeams() { ); } +// Initialize teams DataTable +function initTeamsTable() { + teamsDatatable = $('#teams-table').DataTable({ + order: [[0, 'asc']], + dom: 'RBltpi', + stateSave: true, + buttons: [], + processing: true, + serverSide: true, + ajax: { + url: $('#teams-table').data('source'), + type: 'POST' + }, + colReorder: { + fixedColumnsLeft: 1000000 // Disable reordering + }, + columnDefs: [{ + targets: [0, 1], + orderable: true, + searchable: false + }, { + targets: [2], + searchable: false, + orderable: true + }, { + targets: [3], + searchable: false, + orderable: false, + sWidth: '1%' + }] + }); +} + +initTeamsTable(); initLeaveTeams(); diff --git a/app/assets/stylesheets/themes/scinote.scss b/app/assets/stylesheets/themes/scinote.scss index 27313997c..87e4d2b45 100644 --- a/app/assets/stylesheets/themes/scinote.scss +++ b/app/assets/stylesheets/themes/scinote.scss @@ -732,6 +732,15 @@ a[data-toggle="tooltip"] { text-align: center; } +// Teams datatable +.teams-datatable { + margin-bottom: 20px; + + .dataTables_paginate { + float: right; + } +} + /** Users datatable */ .panel-team-users .panel-body { padding-bottom: 0; diff --git a/app/controllers/users/settings_controller.rb b/app/controllers/users/settings_controller.rb index 07483f301..68752e4c6 100644 --- a/app/controllers/users/settings_controller.rb +++ b/app/controllers/users/settings_controller.rb @@ -9,6 +9,7 @@ class Users::SettingsController < ApplicationController :teams, :team, :create_team, + :teams_datatable, :team_users_datatable, :tutorial, :reset_tutorial, @@ -114,6 +115,14 @@ class Users::SettingsController < ApplicationController end end + def teams_datatable + respond_to do |format| + format.json do + render json: ::TeamsDatatable.new(view_context, @user) + end + end + end + def team_users_datatable respond_to do |format| format.json { diff --git a/app/datatables/teams_datatable.rb b/app/datatables/teams_datatable.rb new file mode 100644 index 000000000..2ac27dfdd --- /dev/null +++ b/app/datatables/teams_datatable.rb @@ -0,0 +1,106 @@ +class TeamsDatatable < AjaxDatatablesRails::Base + include InputSanitizeHelper + + def_delegator :@view, :link_to + def_delegator :@view, :team_path + def_delegator :@view, :leave_user_team_html_path + + MEMEBERS_SORT_COL = 'members'.freeze + + def initialize(view, user) + super(view) + @user = user + end + + def sortable_columns + @sortable_columns ||= [ + 'Team.name', + 'UserTeam.role', + MEMEBERS_SORT_COL + ] + end + + private + + # Returns json of current samples (already paginated) + def data + records.map do |record| + { + 'DT_RowId': record.id, + '0': if record.admin? + link_to(escape_input(record.team.name), team_path(record.team)) + else + escape_input(record.team.name) + end, + '1': escape_input(record.role_str), + '2': if record.guest? + I18n.t('users.settings.teams.index.na') + else + record.team.users.count + end, + '3': leave_team_button(record) + } + end + end + + # Overwrite default pagination method as here + # we need to be able work also with arrays + def paginate_records(records) + records.to_a.drop(offset).first(per_page) + end + + def load_paginator + self + end + + # Overwrite default sort method to handle custom members column + # which is calculated in code and not present in DB + def sort_records(records) + if params[:order].present? && params[:order].length == 1 + if sort_column(params[:order].values[0]) == MEMEBERS_SORT_COL + records = records.sort_by(&proc { |ut| ut.team.users.count }) + if params[:order].values[0]['dir'] == 'asc' + return records + elsif params[:order].values[0]['dir'] == 'desc' + return records.reverse + end + else + super(records) + end + else + super(records) + end + end + + # If user is last admin of team, don't allow + # him/her to leave team + def leave_team_button(user_team) + button = " + + #{I18n.t('users.settings.teams.index.leave')} + " + team = user_team.team + if user_team.admin? && team.user_teams.where(role: 2).count <= 1 + button.prepend('
') + button << '
' + else + button = link_to( + button.html_safe, + leave_user_team_html_path(user_team, format: :json), + remote: true, class: 'btn btn-default btn-xs', type: 'button', + data: { action: 'leave-user-team' } + ) + end + button + end + + # Query database for records (this will be later paginated and filtered) + # after that "data" function will return json + def get_raw_records + UserTeam + .includes(:team) + .references(:team) + .where(user: @user) + end +end diff --git a/app/views/users/settings/teams.html.erb b/app/views/users/settings/teams.html.erb index 34e6f038d..00c029a7f 100644 --- a/app/views/users/settings/teams.html.erb +++ b/app/views/users/settings/teams.html.erb @@ -22,71 +22,19 @@ <% if @member_of > 0 %> - - - - - - - - - - - - - <% @user_teams.each do |user_team| %> - <% team = user_team.team %> +
+
<%=t "users.settings.teams.index.thead_name" %><%=t "users.settings.teams.index.thead_role" %><%=t "users.settings.teams.index.thead_members" %> 
+ - - - - - - + + + + - <% end %> - -
- <% if user_team.admin? %> - <%= link_to team.name, team_path(team) %> - <% else %> - <%= team.name %> - <% end %> - <%= user_team.role_str %> - <% if user_team.guest? %> - <%= t("users.settings.teams.index.na") %> - <% else %> - <%= team.users.count %> - <% end %> - - - <% if user_team.admin? && team.user_teams.where(role: 2).count <= 1 %> -
- - -
- <% else %> - <%= link_to leave_user_team_html_path(user_team, format: :json), - remote: true, - class: 'btn btn-default btn-xs', - type: 'button', - data: { action: 'leave-user-team' } do %> - - - <% end %> - <% end %> -
<%= t("users.settings.teams.index.thead_name") %><%= t("users.settings.teams.index.thead_role") %><%= t("users.settings.teams.index.thead_members") %> 
+ + + + <% else %>
<% end %> @@ -94,4 +42,5 @@ <%= render partial: "users/settings/teams/leave_user_team_modal.html.erb" %> +<%= stylesheet_link_tag 'datatables' %> <%= javascript_include_tag "users/settings/teams" %> diff --git a/config/routes.rb b/config/routes.rb index 62555b648..d9d10ff3d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -63,6 +63,9 @@ Rails.application.routes.draw do get 'users/settings/teams/:team_id/description', to: 'users/settings#team_description', as: 'team_description' + post 'users/settings/teams/teams_datatable', + to: 'users/settings#teams_datatable', + as: 'teams_datatable' post 'users/settings/teams/:team_id/users_datatable', to: 'users/settings#team_users_datatable', as: 'team_users_datatable'