Skip to content

Commit

Permalink
Merge pull request #2746 from sul-dlss/decommission-collections#2629
Browse files Browse the repository at this point in the history
Allow collections to be decommissioned
  • Loading branch information
justinlittman authored Sep 27, 2022
2 parents 4428a65 + 31fc0b8 commit ffa75ff
Show file tree
Hide file tree
Showing 31 changed files with 480 additions and 41 deletions.
10 changes: 9 additions & 1 deletion app/assets/stylesheets/collection.scss
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
font-size: large;
}
}

// The pencil icon
.edit {
margin-left: 10px;
Expand All @@ -51,4 +51,12 @@
}
}
}

.admin-section {
background-color: $silver-sand;

label.admin-functions {
@extend h5;
}
}
}
15 changes: 15 additions & 0 deletions app/components/collections/admin_component.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<section class="admin-section p-3 mb-5">
<div class="row">
<div class="col">
<label for="adminFunctionsSelect" class="form-label admin-functions">Admin functions</label>
</div>
<div class="col">
<select id="adminFunctionsSelect" class="form-select" onchange="this.value !== 'select' ? document.querySelector('#collectionAdminSection').src = this.value : document.querySelector('#collectionAdminSection').innerHTML = ''">
<%= options %>
</select>
</div>
</div>
<div class="row pt-3">
<turbo-frame id="collectionAdminSection"></turbo-frame>
</div>
</section>
24 changes: 24 additions & 0 deletions app/components/collections/admin_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# frozen_string_literal: true

module Collections
# Renders the admin functions for a collection
class AdminComponent < ApplicationComponent
def initialize(collection:)
@collection = collection
end

attr_reader :collection

def render?
helpers.user_with_groups.administrator?
end

def options
opts = [
['Select...', 'select']
]
opts << ['Decommission collection', edit_collection_decommission_path(collection)] unless collection.head.decommissioned? # rubocop:disable Layout/LineLength
options_for_select(opts, 'select')
end
end
end
9 changes: 6 additions & 3 deletions app/components/collections/detail_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
<table class="table table-sm mb-5 caption-header">
<caption>Details
<%= link_to edit_collection_version_path(collection_version), aria: { label: 'Edit details' } do %>
<span class="fa-solid fa-pencil-alt edit" aria-hidden="true"></span>
<% end %>
<%= helpers.turbo_frame_tag dom_id(collection_version, :edit),
src: edit_link_collection_version_path(
collection_version,
label: 'Edit details'
),
target: '_top' %>
</caption>

<tbody>
Expand Down
11 changes: 8 additions & 3 deletions app/components/collections/links_component.html.erb
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
<table class="table table-sm mb-5 caption-header">
<caption>Links to related information
<%= link_to edit_collection_version_path(collection_version, anchor: 'links'), aria: { label: 'Edit links to related information' } do %>
<span class="fa-solid fa-pencil-alt edit" aria-hidden="true"></span>
<% end %>
<%= helpers.turbo_frame_tag dom_id(collection_version, :edit_links),
src: edit_link_collection_version_path(
collection_version,
ref: 'links',
label: 'Edit links to related information'
),
target: '_top' %>

</caption>
<tbody>
<tr>
Expand Down
2 changes: 1 addition & 1 deletion app/components/works/admin_component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ def options
['Change owner', edit_owners_path(work)],
['Lock/Unlock', edit_locks_path(work)]
]
opts << ['Decommission', edit_decommission_path(work)] unless work.head.decommissioned?
opts << ['Decommission', edit_work_decommission_path(work)] unless work.head.decommissioned?
options_for_select(opts, 'select')
end
end
Expand Down
47 changes: 47 additions & 0 deletions app/controllers/collection_decommission_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true

# a controller for decommissioning a collection.
class CollectionDecommissionController < ApplicationController
before_action :authenticate_user!
verify_authorized

def edit
authorize! :collection_decommission
end

def update
authorize! :collection_decommission

collection = Collection.find(params[:id])
# Check that collection contains only NO items or ONLY DECOMMISSIONED items
if collection.works_without_decommissioned.any?
flash[:error] = I18n.t('collection.flash.decommission_failed')
else
decommission!(collection)
flash[:success] = I18n.t('collection.flash.decommissioned')
end
redirect_to collection_path(collection)
end

private

def decommission!(collection)
Collection.transaction do
# NOTE: You might think the `head.collection` bit here is not needed...
# but it is. Why? Because when the event is created in the
# CollectionVersion class, we access the collection **via** the
# collection version. And that in-memory collection instance is a
# different in-memory collection instance than the collection here.
collection.head.collection.event_context = {
user: current_user,
description: I18n.t('collection.flash.decommissioned')
}
collection.head.decommission!
collection.update!(
managed_by: [],
depositors: [],
reviewed_by: []
)
end
end
end
6 changes: 5 additions & 1 deletion app/controllers/collection_versions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,15 @@ def update

# We render this link lazily because it requires doing a query to see if the user has access.
# The access can vary depending on the user and the state of the collection.
# NOTE, the "ref" parameter is used to create the anchor as well as the dom_id for the turbo-frame
# so when you link to this method ensure the dom_id or the containing frame matches the target anchor.
def edit_link
collection_version = CollectionVersion.find(params[:id])
label = params.fetch(:label) { "Edit #{collection_version.name}" }
render partial: 'edit_link', locals: {
collection_version:,
name: collection_version.name
label:,
anchor: params[:ref]
}
end

Expand Down
5 changes: 5 additions & 0 deletions app/controllers/collections_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,11 @@ def edit_link
}
end

def admin
@collection = Collection.find(params[:id])
authorize! @collection
end

private

def update_params
Expand Down
4 changes: 4 additions & 0 deletions app/models/collection_version.rb
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,10 @@ def accessioned?
transition new: :first_draft
transition %i[first_draft version_draft] => same
end

event :decommission do
transition all => :decommissioned
end
end

def updatable?
Expand Down
10 changes: 10 additions & 0 deletions app/policies/collection_decommission_policy.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true

# Authorization policy for Collection decommission operations
class CollectionDecommissionPolicy < ApplicationPolicy
alias_rule :edit?, to: :update?

def update?
administrator?
end
end
11 changes: 9 additions & 2 deletions app/policies/collection_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,17 @@ class CollectionPolicy < ApplicationPolicy
alias_rule :edit?, to: :update?
alias_rule :delete?, to: :destroy?
alias_rule :manage_email_preferences?, to: :review?
alias_rule :admin?, to: :update?

# Return the relation defining the collections you can deposit into, manage or review.
# Return the relation defining the collections you can deposit into, manage,
# or review, and removing decommissioned collections unless administrator.
relation_scope :deposit do |relation|
relation.where(id: user.deposits_into_ids + user.manages_collection_ids + user.reviews_collection_ids)
new_relation = relation.where(
id: user.deposits_into_ids + user.manages_collection_ids + user.reviews_collection_ids
)
return new_relation if administrator?

relation.joins(:head).where.not(head: { state: 'decommissioned' }).and(new_relation)
end

def update?
Expand Down
15 changes: 15 additions & 0 deletions app/policies/collection_version_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,17 @@ class CollectionVersionPolicy < ApplicationPolicy
alias_rule :edit?, to: :update?
alias_rule :delete?, to: :destroy?

# Return the relation defining the collections you can view and removing decommissioned works unless administrator.
scope_for :relation do |relation|
return relation if administrator?

relation.where.not(state: 'decommissioned').and(
relation.where(
collection_id: user.deposits_into_ids + user.manages_collection_ids + user.reviews_collection_ids
)
)
end

def update?
return false unless record.updatable?

Expand All @@ -19,6 +30,10 @@ def destroy?
(administrator? || manages_collection?(record.collection)) && record.persisted? && record.version_draft?
end

def deposit?
record.updatable? && show?
end

delegate :administrator?, :collection_creator?, to: :user_with_groups
delegate :collection, to: :record
end
2 changes: 1 addition & 1 deletion app/policies/work_policy.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
class WorkPolicy < ApplicationPolicy
alias_rule :delete?, to: :destroy?

# Return the relation defining the collections you can view and removing decommissioned works unless administrator.
# Return the relation defining the works you can view and removing decommissioned works unless administrator.
scope_for :relation do |relation|
new_relation = relation.where(collection_id: user.manages_collection_ids + user.reviews_collection_ids).or(
relation.where(owner: user)
Expand Down
15 changes: 15 additions & 0 deletions app/views/collection_decommission/edit.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<turbo-frame id='collectionAdminSection'>
<%= form_with url: collection_decommission_path(params[:id]), method: :put, data: { turbo: false } do |form| %>
<div data-controller="decommission">
<div class="form-check mt-3">
<input class="form-check-input" type="checkbox" value="" id="confirmCheckbox" data-decommission-target="confirm" data-action="decommission#change">
<label class="form-check-label" for="confirmCheckbox">
I confirm this collection has been decommissioned in Argo and <span class="text-danger">understand this cannot be undone</span>.
</label>
</div>
<fieldset data-decommission-target="submit">
<%= form.submit "Decommission collection from H2", class: 'btn btn-primary mt-3' %>
</fieldset>
</div>
<% end %>
</turbo-frame>
4 changes: 2 additions & 2 deletions app/views/collection_versions/_edit_link.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<%= turbo_frame_tag dom_id(collection_version, :edit) do %>
<%= turbo_frame_tag dom_id(collection_version, ['edit', anchor].compact.join('_')) do %>
<% if allowed_to?(:update?, collection_version) %>
<%= link_to edit_collection_version_path(collection_version), aria: { label: "Edit #{name}" } do %>
<%= link_to edit_collection_version_path(collection_version, anchor: anchor), aria: { label: } do %>
<%= tag.span class: 'fa-solid fa-pencil-alt edit' %>
<% end %>
<% end %>
Expand Down
2 changes: 2 additions & 0 deletions app/views/collections/_collection.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<section id="<%= dom_id(collection) %>" data-controller="work-type">
<%= render Collections::Show::SettingsHeaderComponent.new(collection_version: collection.head) %>
<%= render Works::WorkTypeModalComponent.new %>
<turbo-frame id="collectionAdminFrame" src="<%= admin_collection_path(collection) %>">
</turbo-frame>
<%= render Collections::ReleaseComponent.new(collection: collection) %>
<%= render Collections::TermsOfUseComponent.new(collection: collection) %>
<%= render Collections::ParticipantsComponent.new(collection: collection) %>
Expand Down
5 changes: 4 additions & 1 deletion app/views/collections/_deposit_button.html.erb
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<%= turbo_frame_tag dom_id(collection, :deposit) do %>
<% if allowed_to?(:create?, WorkVersion.new(work: Work.new(collection: collection))) %>
<%
if allowed_to?(:create?, WorkVersion.new(work: Work.new(collection: collection))) &&
allowed_to?(:deposit?, collection.head)
%>
<%= button_tag '+ Deposit to this collection',
data: {
destination: new_collection_work_path(collection),
Expand Down
3 changes: 3 additions & 0 deletions app/views/collections/admin.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
<turbo-frame id="collectionAdminFrame">
<%= render Collections::AdminComponent.new(collection: @collection) %>
</turbo-frame>
6 changes: 3 additions & 3 deletions app/views/work_decommission/edit.html.erb
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
<turbo-frame id='workAdminSection'>
<%= form_with url: decommission_path(params[:id]), method: :put, data: {turbo: false} do |form| %>
<%= form_with url: work_decommission_path(params[:id]), method: :put, data: {turbo: false} do |form| %>
<div data-controller="decommission">
<div class="form-check mt-3">
<input class="form-check-input" type="checkbox" value="" id="confirmCheckbox" data-decommission-target="confirm" data-action="decommission#change">
<label class="form-check-label" for="confirmCheckbox">
I confirm this item has been decommissioned in Argo and <span class="text-danger">understand this cannot be undone</span>.
I confirm this item has been decommissioned in Argo and <span class="text-danger">understand this cannot be undone</span>.
</label>
</div>
<fieldset data-decommission-target="submit">
<%= form.submit "Decommission from H2", class: 'btn btn-primary mt-3' %>
</fieldset>
</div>
<% end %>
</turbo-frame>
</turbo-frame>
Loading

0 comments on commit ffa75ff

Please sign in to comment.