diff --git a/app/controllers/admin/schools_controller.rb b/app/controllers/admin/schools_controller.rb index 02b027316..eebc90f59 100644 --- a/app/controllers/admin/schools_controller.rb +++ b/app/controllers/admin/schools_controller.rb @@ -2,6 +2,8 @@ module Admin class SchoolsController < Admin::ApplicationController + helper_method :school_role_users_by_id + def verify service = SchoolVerificationService.new(requested_resource) @@ -33,5 +35,19 @@ def default_sorting_attribute def default_sorting_direction :desc end + + private + + def school_role_users_by_id + @school_role_users_by_id ||= fetch_users_batch(school_role_user_ids) + end + + def school_role_user_ids + requested_resource.roles.where(role: SchoolRolesField::DISPLAYED_ROLES).filter_map(&:user_id).uniq + end + + def fetch_users_batch(user_ids) + User.from_userinfo(ids: user_ids).index_by(&:id) + end end end diff --git a/app/dashboards/school_dashboard.rb b/app/dashboards/school_dashboard.rb index a642cb89b..213c8da35 100644 --- a/app/dashboards/school_dashboard.rb +++ b/app/dashboards/school_dashboard.rb @@ -11,6 +11,7 @@ class SchoolDashboard < Administrate::BaseDashboard # on pages throughout the dashboard. ATTRIBUTE_TYPES = { id: Field::String, + code: Field::String, creator: Field::BelongsTo.with_options(class_name: 'User'), postal_code: Field::String, creator_role: Field::String, @@ -25,6 +26,7 @@ class SchoolDashboard < Administrate::BaseDashboard classes: Field::HasMany, lessons: Field::HasMany, projects: Field::HasMany, + roles: SchoolRolesField, reference: Field::String, district_name: Field::String, district_nces_id: Field::String, @@ -43,6 +45,7 @@ class SchoolDashboard < Administrate::BaseDashboard # Feel free to add, remove, or rearrange items. COLLECTION_ATTRIBUTES = %i[ name + code user_origin reference country_code @@ -57,8 +60,10 @@ class SchoolDashboard < Administrate::BaseDashboard # an array of attributes that will be displayed on the model's show page. SHOW_PAGE_ATTRIBUTES = %i[ name + code user_origin creator + roles creator_role creator_department reference diff --git a/app/fields/school_roles_field.rb b/app/fields/school_roles_field.rb new file mode 100644 index 000000000..69143467d --- /dev/null +++ b/app/fields/school_roles_field.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +require 'administrate/field/base' + +class SchoolRolesField < Administrate::Field::Base + DISPLAYED_ROLES = %w[owner teacher].freeze + + def roles + @roles ||= data.where(role: DISPLAYED_ROLES).sort_by(&:created_at) + end + + def user_display(role, users_by_id = {}) + user = users_by_id[role.user_id] + user.present? ? user_dashboard.display_resource(user) : role.user_id + end + + private + + def user_dashboard + @user_dashboard ||= UserDashboard.new + end +end diff --git a/app/views/fields/school_roles_field/_show.html.erb b/app/views/fields/school_roles_field/_show.html.erb new file mode 100644 index 000000000..eb05fdddf --- /dev/null +++ b/app/views/fields/school_roles_field/_show.html.erb @@ -0,0 +1,26 @@ +<%# +Administrate field partial for SchoolRolesField in show view +%> + +<% if field.roles.any? %> + + + + + + + + + + <% field.roles.each do |role| %> + + + + + + <% end %> + +
RoleUserCreated
<%= role.role.humanize %><%= field.user_display(role, school_role_users_by_id) %><%= l(role.created_at) %>
+<% else %> + <%= t("administrate.fields.has_many.none", default: "–") %> +<% end %> diff --git a/spec/features/admin/schools_spec.rb b/spec/features/admin/schools_spec.rb index 8d57f21e0..b5131e35d 100644 --- a/spec/features/admin/schools_spec.rb +++ b/spec/features/admin/schools_spec.rb @@ -77,6 +77,44 @@ end end + describe 'GET #show with roles' do + let(:creator) { create(:user) } + let(:school) { create(:school, creator_id: creator.id) } + let(:owner) { create(:user, name: 'Olivia Owner', email: 'owner@example.com') } + let(:teacher) { create(:user, name: 'Tariq Teacher', email: 'teacher@example.com') } + let(:student) { create(:user, name: 'Sam Student', email: 'student@example.com') } + let(:role_users) do + [ + owner, + teacher + ] + end + + before do + create(:owner_role, school:, user_id: owner.id) + create(:teacher_role, school:, user_id: teacher.id) + create(:student_role, school:, user_id: student.id) + + allow(User).to receive(:from_userinfo).with(ids: creator.id).and_return([creator]) + allow(User).to receive(:from_userinfo).with(ids: contain_exactly(owner.id, teacher.id)).and_return(role_users) + + get admin_school_path(school) + end + + it 'lists owner and teacher roles with names and emails' do + expect(User).to have_received(:from_userinfo).with(ids: contain_exactly(owner.id, teacher.id)).once + expect(response.body).to include('Owner') + expect(response.body).to include('Olivia Owner (owner@example.com)') + expect(response.body).to include('Teacher') + expect(response.body).to include('Tariq Teacher (teacher@example.com)') + end + + it 'does not list student roles' do + expect(response.body).not_to include('Sam Student') + expect(response.body).not_to include('student@example.com') + end + end + describe 'POST #verify' do let(:creator) { create(:user) } let(:verified_at) { nil }