Skip to content

Commit

Permalink
UI for adding workflow roles. Fixes #1037
Browse files Browse the repository at this point in the history
  • Loading branch information
jcoyne committed Oct 20, 2016
1 parent 7169243 commit ca956b1
Show file tree
Hide file tree
Showing 14 changed files with 282 additions and 21 deletions.
9 changes: 1 addition & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,14 +116,7 @@ Load the workflows, workflow states, transitions and user roles:
$ rails curation_concerns:workflow:load
```

Now that the Roles are loaded, grant all the roles to all the users. This works for testing, but you probably don't want this in production:
```ruby
CurationConcerns::Workflow::PermissionGenerator.call(roles: Sipity::Role.all,
workflow: Sipity::Workflow.last,
agents: User.all)
```

In the future this functionality should be available in the user interface.
Now that the Roles are loaded, grant the appropriate roles to the users by visiting the "Workflow Roles" section of the admin dashboard

[Further documentation](https://github.com/projecthydra/curation_concerns/wiki/Defining-a-Workflow) for defining and customizing workflows.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,13 @@ module AdminControllerBehavior
extend ActiveSupport::Concern

included do
cattr_accessor :configuration
self.configuration = CurationConcerns.config.dashboard_configuration
include AdminPage
before_action :require_permissions
before_action :load_configuration
layout "admin"
end

def index
@resource_statistics = @configuration.fetch(:data_sources).fetch(:resource_stats).new
render 'index'
end
def index
@resource_statistics = @configuration.fetch(:data_sources).fetch(:resource_stats).new
render 'index'
end

def search_builder
Expand All @@ -33,10 +30,6 @@ def require_permissions
authorize! :read, :admin_dashboard
end

def load_configuration
@configuration = self.class.configuration.with_indifferent_access
end

# Loads the index action if it's only defined in the configuration.
def action_missing(action)
index if @configuration[:actions].include?(action)
Expand Down
18 changes: 18 additions & 0 deletions app/controllers/concerns/curation_concerns/admin_page.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
module CurationConcerns
module AdminPage
extend ActiveSupport::Concern

included do
cattr_accessor :configuration
self.configuration = CurationConcerns.config.dashboard_configuration
before_action :load_configuration
layout "admin"
end

private

def load_configuration
@configuration = self.class.configuration.with_indifferent_access
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module CurationConcerns
module Admin
class WorkflowRolesController < ApplicationController
include AdminPage
before_action :require_permissions

def index
@presenter = WorkflowRolePresenter.new
end

def destroy
responsibility = Sipity::WorkflowResponsibility.find(params[:id])
authorize! :destroy, responsibility
responsibility.destroy
redirect_to admin_workflow_roles_path
end

def create
authorize! :create, Sipity::WorkflowResponsibility
form = Forms::WorkflowResponsibilityForm.new(params[:sipity_workflow_responsibility])
begin
form.save!
rescue ActiveRecord::RecordNotUnique
logger.info "Not unique *****\n\n\n"
end
redirect_to admin_workflow_roles_path
end

private

def require_permissions
authorize! :read, :admin_dashboard
end
end
end
end
42 changes: 42 additions & 0 deletions app/forms/curation_concerns/forms/workflow_responsibility_form.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
module CurationConcerns
module Forms
class WorkflowResponsibilityForm
def initialize(params = {})
model_instance.workflow_role_id = params[:workflow_role_id]
if params[:user_id]
user = ::User.find(params[:user_id])
model_instance.agent = user.to_sipity_agent
end
end

def model_instance
@model ||= Sipity::WorkflowResponsibility.new
end

def to_model
model_instance
end

delegate :model_name, :to_key, :workflow_role_id, :persisted?, :save!, to: :model_instance

def user_id
nil
end

def user_options
::User.all
end

# The select options for choosing a responsibility
def workflow_role_options
Sipity::WorkflowRole.all.map { |wf_role| [label(wf_role), wf_role.id] }
end

private

def label(wf_role)
"#{wf_role.workflow.name} - #{wf_role.role.name}"
end
end
end
end
1 change: 1 addition & 0 deletions app/models/concerns/curation_concerns/ability.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ def admin_permissions
alias_action :discover, to: :read

can :manage, curation_concerns_models
can :manage, Sipity::WorkflowResponsibility
end

# Override this method in your ability model if you use a different group
Expand Down
40 changes: 40 additions & 0 deletions app/presenters/curation_concerns/admin/workflow_role_presenter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
module CurationConcerns
module Admin
class WorkflowRolePresenter
def users
::User.all
end

def presenter_for(user)
agent = user.sipity_agent
return unless agent
AgentPresenter.new(agent)
end

class AgentPresenter
def initialize(agent)
@agent = agent
end

def responsibilities
@agent.workflow_responsibilities.each do |responsibility|
yield ResponsibilityPresenter.new(responsibility)
end
end
end

class ResponsibilityPresenter
def initialize(responsibility)
@responsibility = responsibility
@wf_role = responsibility.workflow_role
end

attr_accessor :responsibility

def label
"#{@wf_role.workflow.name} - #{@wf_role.role.name}"
end
end
end
end
end
45 changes: 45 additions & 0 deletions app/views/curation_concerns/admin/workflow_roles/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<div class="<%= "dashboard-#{action_name}" %>">
<div class="wrapper">
<div class="widget widget-default">
<table class="table table-striped">
<thead>
<th><%= t('.header.user') %></th>
<th><%= t('.header.roles') %></th>
</thead>
<tbody>
<% @presenter.users.each do |user| %>
<tr>
<td><%= user.user_key %></td>
<% agent_presenter = @presenter.presenter_for(user) %>
<% if agent_presenter %>
<td>
<ul>
<% agent_presenter.responsibilities do |responsibility_presenter| %>
<li><%= responsibility_presenter.label %>
<%= link_to admin_workflow_role_path(responsibility_presenter.responsibility),
method: :delete,
data: { confirm: t('.delete.confirm') } do %>
<span class="delete">&times;</span>
<% end %>
</li>
<% end %>
</ul>
</td>
<% else %>
<td><%= t('.no_roles') %></td>
<% end %>
</tr>
<% end %>
</tbody>
</table>

<h2><%= t('.new_role') %></h2>
<%= simple_form_for CurationConcerns::Forms::WorkflowResponsibilityForm.new, url: admin_workflow_roles_path do |f| %>
<%= f.input :user_id, as: :select, collection: f.object.user_options %>
<%= f.input :workflow_role_id, as: :select, collection: f.object.workflow_role_options %>
<%= f.submit %>
<% end %>
</div>
</div>
</div>

15 changes: 15 additions & 0 deletions config/locales/curation_concerns.en.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,15 @@
en:
curation_concerns:
admin:
workflow_roles:
index:
header:
user: User
roles: Roles
no_roles: No roles
new_role: "Grant a role to a user:"
delete:
confirm: Are you sure?
api:
accepted:
default: "Your request has been accepted for processing, but processing is not complete. See job for more info."
Expand Down Expand Up @@ -35,6 +45,7 @@ en:
index: "Admin Dashboard"
resource_details: "Resource Details"
workflow: "Workflow"
workflow_roles: "Workflow Roles"
division:
name: "Your Division at Institution"
homepage_url: "#"
Expand Down Expand Up @@ -225,6 +236,10 @@ en:
identifier_tesim: "Identifier"
file_manager:
link_text: 'File Manager'
helpers:
submit:
sipity_workflow_responsibility:
create: "Add"
simple_form:
required:
html: '<span class="label label-info required-tag">required</span>'
Expand Down
1 change: 1 addition & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
get '/', action: :index, as: :index
get :resource_details
get :workflow
resources :workflow_roles
end

# mount BrowseEverything::Engine => '/remote_files/browse'
Expand Down
3 changes: 2 additions & 1 deletion lib/curation_concerns/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,8 @@ def dashboard_configuration
menu: {
index: {},
resource_details: {},
workflow: {}
workflow: {},
workflow_roles: {}
},
actions: {
index: {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'spec_helper'

RSpec.describe CurationConcerns::Admin::WorkflowRolesController, :no_clean do
routes { CurationConcerns::Engine.routes }

describe "#get" do
context "when you have permission" do
before do
allow(controller).to receive(:authorize!).with(:read, :admin_dashboard).and_return(true)
end

it "works" do
get :index
expect(response).to be_success
expect(assigns[:presenter]).to be_kind_of CurationConcerns::Admin::WorkflowRolePresenter
end
end

context "when they don't have permission" do
it "throws a CanCan error" do
get :index
expect(response).to redirect_to new_user_session_path
end
end
end
end
17 changes: 17 additions & 0 deletions spec/features/workflow_roles_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
require 'spec_helper'

RSpec.describe "Manage workflow roles", type: :feature do
let(:user) { create(:user) }
before do
allow_any_instance_of(CurationConcerns::Admin::WorkflowRolesController).to receive(:authorize!).with(:read, :admin_dashboard).and_return(true)
CurationConcerns::Workflow::WorkflowImporter.generate_from_json_file(path: "#{EngineCart.destination}/config/workflows/generic_work_workflow.json")
CurationConcerns::Workflow::PermissionGenerator.call(roles: Sipity::Role.all,
workflow: Sipity::Workflow.last,
agents: user)
end

it "shows the roles" do
visit '/admin/workflow_roles'
expect(page).to have_content 'generic_work - reviewing'
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
require 'spec_helper'

describe CurationConcerns::Forms::WorkflowResponsibilityForm, :no_clean do
let(:instance) { described_class.new }

describe "#initialize" do
let(:user) { create(:user) }
let(:instance) { described_class.new(user_id: user.id, workflow_role_id: 7) }
subject { instance.model_instance }
it "creates an agent and sets the workflow_role_id" do
expect(subject.agent).to be_kind_of Sipity::Agent
expect(subject.workflow_role_id).to eq 7
end
end

describe "#user_options" do
subject { instance.user_options }
it { is_expected.to eq User.all }
end

describe "#workflow_role_options" do
let(:workflow) { instance_double(Sipity::Workflow, name: 'generic_work') }
let(:role1) { instance_double(Sipity::Role, name: 'foo') }
let(:role2) { instance_double(Sipity::Role, name: 'bar') }
let(:wf_role1) { instance_double(Sipity::WorkflowRole, workflow: workflow, role: role1, id: 1) }
let(:wf_role2) { instance_double(Sipity::WorkflowRole, workflow: workflow, role: role2, id: 2) }
before do
allow(Sipity::WorkflowRole).to receive(:all).and_return([wf_role1, wf_role2])
end
subject { instance.workflow_role_options }
it { is_expected.to eq [['generic_work - foo', 1], ['generic_work - bar', 2]] }
end
end

0 comments on commit ca956b1

Please sign in to comment.