diff --git a/app/controllers/staffs/org_units_controller.rb b/app/controllers/staffs/org_units_controller.rb new file mode 100644 index 0000000..12adb57 --- /dev/null +++ b/app/controllers/staffs/org_units_controller.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class Staffs::OrgUnitsController < ApplicationController + before_action :set_org_unit, only: :show + + # GET /staff/org_units + def index + authorize [:staff, OrgUnit] + @org_units = policy_scope( + OrgUnit, + policy_scope_class: Staff::OrgUnitPolicy::Scope, + ).page(params[:page]) + end + + # GET /staff/org_units/:id + def show + authorize [:staff, @org_unit] + end + +private + + def set_org_unit + @org_unit = OrgUnit.find params[:id] + end +end diff --git a/app/policies/staff/org_unit_policy.rb b/app/policies/staff/org_unit_policy.rb new file mode 100644 index 0000000..068d675 --- /dev/null +++ b/app/policies/staff/org_unit_policy.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +class Staff::OrgUnitPolicy < ApplicationPolicy + def index? + return false if restricted? + + account&.superuser? + end + + def show? + return false if restricted? + + account&.superuser? + end + + class Scope < Scope + def resolve + return scope.none if restricted? + + return scope.all if account&.superuser? + + scope.none + end + end +end diff --git a/app/views/staffs/home/show.html.erb b/app/views/staffs/home/show.html.erb index 3518991..32207f1 100644 --- a/app/views/staffs/home/show.html.erb +++ b/app/views/staffs/home/show.html.erb @@ -41,5 +41,12 @@ staff_org_unit_kinds_path %> <% end %> + + <% if policy([:staff, OrgUnit]).index? %> +
  • + <%= link_to OrgUnit.model_name.human(count: 0), + staff_org_units_path %> +
  • + <% end %> diff --git a/app/views/staffs/org_units/_table.html.erb b/app/views/staffs/org_units/_table.html.erb new file mode 100644 index 0000000..aba7d82 --- /dev/null +++ b/app/views/staffs/org_units/_table.html.erb @@ -0,0 +1,27 @@ + + + + + + + + + + + <% org_units.each do |org_unit| %> + + + + + + <% end %> + +
    + <%= OrgUnit.human_attribute_name :short_name %> + + <%= OrgUnit.human_attribute_name :name %> +
    <%= org_unit.short_name %><%= org_unit.name %> + <% if policy([:staff, org_unit]).show? %> + <%= open_action [:staff, org_unit] %> + <% end %> +
    diff --git a/app/views/staffs/org_units/index.html.erb b/app/views/staffs/org_units/index.html.erb new file mode 100644 index 0000000..f3a063e --- /dev/null +++ b/app/views/staffs/org_units/index.html.erb @@ -0,0 +1,9 @@ +
    + <%= nav_breadcrumb( + [translate(:staff_services), staff_root_path], + OrgUnit.model_name.human(count: 0), + ) %> + + <%= render partial: 'table', locals: { org_units: @org_units } %> + <%= pagination @org_units %> +
    diff --git a/app/views/staffs/org_units/show.html.erb b/app/views/staffs/org_units/show.html.erb new file mode 100644 index 0000000..fa51261 --- /dev/null +++ b/app/views/staffs/org_units/show.html.erb @@ -0,0 +1,39 @@ +
    + <%= nav_breadcrumb( + [translate(:staff_services), staff_root_path], + [OrgUnit.model_name.human(count: 0), staff_org_units_path], + @org_unit.name, + ) %> + +
    +
    <%= OrgUnit.human_attribute_name :kind %>
    +
    + <% if @org_unit.kind.nil? %> + <%= none %> + <% elsif policy([:staff, @org_unit.kind]).show? %> + <%= link_to @org_unit.kind.name, + [:staff, @org_unit.kind] %> + <% else %> + <%= @org_unit.kind.name %> + <% end %> +
    + +
    <%= OrgUnit.human_attribute_name :short_name %>
    +
    <%= @org_unit.short_name %>
    + +
    <%= OrgUnit.human_attribute_name :name %>
    +
    <%= @org_unit.name %>
    + +
    <%= OrgUnit.human_attribute_name :parent %>
    +
    + <% if @org_unit.parent.nil? %> + <%= none %> + <% elsif policy([:staff, @org_unit.parent]).show? %> + <%= link_to @org_unit.parent.name, + [:staff, @org_unit.parent] %> + <% else %> + <%= @org_unit.parent.name %> + <% end %> +
    +
    +
    diff --git a/config/locales/activerecord/en.yml b/config/locales/activerecord/en.yml index 1f0c09b..b21f2e6 100644 --- a/config/locales/activerecord/en.yml +++ b/config/locales/activerecord/en.yml @@ -14,6 +14,10 @@ en: federal_subject: one: State many: States + org_unit: + one: Organizational unit + few: Organizational unit + many: Organizational units org_unit_kind: one: Organizational unit type few: Organizational unit types @@ -68,6 +72,12 @@ en: centre: Administrative centre number: Number timezone: Time zone + org_unit: + id: ID + kind: Type + short_name: Short name + name: Name + parent: Parent org_unit_kind: id: ID codename: Codename diff --git a/config/locales/activerecord/ru.yml b/config/locales/activerecord/ru.yml index d9776b0..34268da 100644 --- a/config/locales/activerecord/ru.yml +++ b/config/locales/activerecord/ru.yml @@ -14,6 +14,10 @@ ru: federal_subject: one: Регион many: Регионы + org_unit: + one: Организационное подразделение + few: Организационные подразделения + many: Организационные подразделения org_unit_kind: one: Тип организационных подразделений few: Типы организационных подразделений @@ -68,6 +72,12 @@ ru: centre: Административный центр number: Номер timezone: Часовой пояс + org_unit: + id: ID + kind: Тип + short_name: Короткое развание + name: Название + parent: Родитель org_unit_kind: id: ID codename: Кодовое имя diff --git a/config/routes.rb b/config/routes.rb index 27a2380..09348a3 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -65,6 +65,8 @@ Rails.application.routes.draw do resources :org_unit_kinds, param: :codename, only: %i[index show] + resources :org_units, only: %i[index show] + resources :people, only: %i[index show new create] do resources :person_comments, path: 'comments', diff --git a/spec/policies/staff/org_unit_policy_spec.rb b/spec/policies/staff/org_unit_policy_spec.rb new file mode 100644 index 0000000..eaa78f4 --- /dev/null +++ b/spec/policies/staff/org_unit_policy_spec.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Staff::OrgUnitPolicy do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/requests/staff/org_units/index_spec.rb b/spec/requests/staff/org_units/index_spec.rb new file mode 100644 index 0000000..f01d22d --- /dev/null +++ b/spec/requests/staff/org_units/index_spec.rb @@ -0,0 +1,71 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'GET /staff/org_units' do + let(:current_account) { create :superuser_account } + + let :org_units_count do + [0, 1, rand(2..4), rand(5..10), rand(20..40)].sample + end + + before do + sign_in current_account.user if current_account&.user + + create_list :some_root_org_unit, org_units_count + + get '/staff/org_units' + end + + for_account_types nil, :usual do + specify do + expect(response).to have_http_status :forbidden + end + end + + for_account_types :superuser do + specify do + expect(response).to have_http_status :ok + end + end + + context 'when there are no organizational units' do + let(:org_units_count) { 0 } + + specify do + expect(response).to have_http_status :ok + end + end + + context 'when there is one organizational unit' do + let(:org_units_count) { 1 } + + specify do + expect(response).to have_http_status :ok + end + end + + context 'when there are few organizational units' do + let(:org_units_count) { rand 2..4 } + + specify do + expect(response).to have_http_status :ok + end + end + + context 'when there are many organizational units' do + let(:org_units_count) { rand 5..10 } + + specify do + expect(response).to have_http_status :ok + end + end + + context 'when there are lot of organizational units' do + let(:org_units_count) { rand 20..40 } + + specify do + expect(response).to have_http_status :ok + end + end +end diff --git a/spec/requests/staff/org_units/show_spec.rb b/spec/requests/staff/org_units/show_spec.rb new file mode 100644 index 0000000..cb895bf --- /dev/null +++ b/spec/requests/staff/org_units/show_spec.rb @@ -0,0 +1,38 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe 'GET /staff/org_units/:id' do + let(:current_account) { create :superuser_account } + + let(:some_org_unit) { create :some_root_org_unit } + + def make_request + get "/staff/org_units/#{some_org_unit.id}" + end + + before do + sign_in current_account.user if current_account&.user + make_request + end + + for_account_types nil, :usual do + specify do + expect(response).to have_http_status :forbidden + end + end + + for_account_types :superuser do + specify do + expect(response).to have_http_status :ok + end + end + + context 'when organizational unit has parent' do + let(:some_org_unit) { create :some_children_org_unit } + + specify do + expect(response).to have_http_status :ok + end + end +end