Skip to content

Commit

Permalink
Begins to integrate the form functionality for the EphemeraBox and Ep…
Browse files Browse the repository at this point in the history
…hemeraFolder resources within EphemeraProjects

Adding routing and minimal support for EphemeraFolders

Implementing a first attempt at supporting EphemeraBox membership and improving the routes for EphemeraBoxes and EphemeraFolders

Ensuring that Resources can have IIIF Manifests exposed using the class method "can_have_manifests?"; Ensuring that EphemeraProjects and EphemeraBoxes are linked using the ContextualPath

Implementing the attributes for the EphemeraFolders; Resolving issues for ScannedResources

Integrating support for membership within EphemeraFolders

Tracking files being merge after the latest rebase

Adding the Factories and test suites for the Ephemera Decorators

Extending the test coverage for the Ephemera* Controllers and Decorators

Extending the test coverage for EphemeraFolder and EphemeraField Controllers; Adding the routes for EphemeraFields

Don't create a real property for append_id

Append_id is a virtual property in Valkyrie that exists on ChangeSets.
It's not something we want to persist - it's something we act on in a
ChangeSetPersister.

Increasing the coverage for the EphemeraFolderDecorator

Use Blacklight's type filter for members.

Works better than a branch in the default view.

Fix discoverability of EphemeraFolders.

Extending the coverage for the Ephemera Decorators; Adding test coverage for the EphemeraBox and Folder ChangeSets

Increasing (and improving upon) the Ephemera Controllers

Increasing the test coverage for EphemeraFolders and the ephemera editor role

Clean up box show view.

Ensures that IIIF Manifests are properly structured for EphemeraFolders

Add parent breadcrumb for boxes.

Add Ephemera Folder Workflow

Also DRYs this up a bit to make it easier to add another workflow later.

Rename project `name` to `title`

Fixes the header.

Add home page links for Ephemera.

Hide Project attributes.

Implement Box Workflow.

Improve parent breadcrumb for folders.

Fix visibility default.

Show workflow state.

Hide thumbnail from show page.

Add Plum Folder Javascript

Adds datatables when appropriate and handles sort title.

Ensure folders are always displayable.

Fix discovery/manifest of Folders.

Removing an unreachable condition branch for manifest access permissions
  • Loading branch information
jrgriffiniii committed Sep 19, 2017
1 parent 9394dcb commit 00a2e31
Show file tree
Hide file tree
Showing 86 changed files with 2,648 additions and 114 deletions.
7 changes: 4 additions & 3 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,12 @@ Metrics/BlockLength:
- 'lib/tasks/dev.rake'
- 'app/models/plum_schema.rb'
- 'app/services/pdf_generator/cover_page_generator.rb'
- 'valhalla/app/change_sets/valhalla/change_set_workflow.rb'
Metrics/ClassLength:
Exclude:
- 'app/change_set_persisters/plum_change_set_persister.rb'
- 'app/change_sets/scanned_resource_change_set.rb'
- 'app/models/ability.rb'
Metrics/MethodLength:
Exclude:
- 'db/migrate/**/*'
Expand All @@ -52,6 +55,7 @@ Metrics/MethodLength:
- 'app/models/schema/plum/local.rb'
- 'spec/services/manifest_builder_spec.rb'
- 'app/services/pdf_generator/cover_page_generator.rb'
- 'app/change_sets/ephemera_folder_change_set.rb'
Metrics/ModuleLength:
Exclude:
- 'app/models/schema/dublin_core.rb'
Expand Down Expand Up @@ -80,8 +84,5 @@ RSpec/VerifiedDoubles:
- 'spec/validators/viewing_hint_validator_spec.rb'
- 'spec/validators/viewing_direction_validator_spec.rb'
- 'spec/models/user_spec.rb'
Metrics/ClassLength:
Exclude:
- 'app/change_set_persisters/plum_change_set_persister.rb'
Lint/UnusedMethodArgument:
AllowUnusedKeywordArguments: true
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -84,4 +84,5 @@ gem 'capistrano', '~> 3.7.1'
gem 'capistrano-passenger'
gem 'capistrano-rails'
gem 'capistrano-rails-console'
gem 'jquery-datatables-rails', '~> 3.4.0'
gem 'prawn'
6 changes: 6 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,11 @@ GEM
inflecto (0.0.2)
io-like (0.3.0)
jmespath (1.3.1)
jquery-datatables-rails (3.4.0)
actionpack (>= 3.1)
jquery-rails
railties (>= 3.1)
sass-rails
jquery-rails (4.3.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
Expand Down Expand Up @@ -778,6 +783,7 @@ DEPENDENCIES
hydra-head
hydra-role-management
iiif_manifest!
jquery-datatables-rails (~> 3.4.0)
jquery-rails
jquery-ui-rails (~> 5.0)
listen
Expand Down
2 changes: 2 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
//= require jquery-ui/sortable
//= require jquery-ui/slider
//= require jquery-ui/datepicker
//= require dataTables/jquery.dataTables
//= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
//= require jqueryui-timepicker-addon
//= require nestedSortable/jquery.mjs.nestedSortable
//= require openseadragon/openseadragon
Expand Down
20 changes: 20 additions & 0 deletions app/assets/javascripts/ephemera_sort_title.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/* ephemera sort title: generate a sort title when the title or language is updated */
var articles = {
'English': ['a', 'an', 'the'],
'Portuguese': ['as', 'um', 'uma', 'umas', 'uns'],
'Spanish': ['el', 'la', 'las', 'los', 'o', 'os']
};

$(document).ready(function(){
$('input[id="ephemera_folder_title"]').change(sort_title);
$('select[id="ephemera_folder_language"]').change(sort_title);
});

function sort_title() {
var sort_title = $('#ephemera_folder_title').val().toLowerCase();
var lang = $('#ephemera_folder_language').find(':selected').filter(':first').text();
if (lang in articles) {
sort_title = sort_title.replace(new RegExp('^(' + articles[lang].join('|') + ')\\s'), '');
}
$('#ephemera_folder_sort_title').val(sort_title);
}
1 change: 1 addition & 0 deletions app/assets/javascripts/figgy_boot.es6
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export default class Initializer {
this.derivative_form = new DerivativeForm
this.universal_viewer = new UniversalViewer
$("select").selectpicker({'liveSearch': true})
$(".datatable").DataTable()
}

initialize_timepicker() {
Expand Down
1 change: 1 addition & 0 deletions app/assets/stylesheets/application.scss
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
*= require jquery-ui/datepicker
*= require jquery-ui/slider
*= require jqueryui-timepicker-addon
*= require dataTables/bootstrap/3/jquery.dataTables.bootstrap
*/
@charset "utf-8";
@import 'variables/typography';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ def initialize(change_set_persister:, change_set:, post_save_resource: nil)

def run
return unless append_id.present?
parent.thumbnail_id = post_save_resource.id if parent.member_ids.blank?
parent.thumbnail_id = post_save_resource.id if parent.respond_to?(:thumbnail_id) && parent.member_ids.blank?
parent.member_ids = parent.member_ids + [post_save_resource.id]
persister.save(resource: parent)
# Re-save to solr unless it's going to be done by save_all
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ def initialize(change_set_persister:, change_set:, post_save_resource: nil)
end

def run
return unless change_set.respond_to?(:apply_remote_metadata?)
IdentifierService.mint_or_update(resource: change_set.model) if mint_ark?
return unless change_set.respond_to?(:source_metadata_identifier)
return unless change_set.apply_remote_metadata?
Expand Down
47 changes: 47 additions & 0 deletions app/change_sets/ephemera_box_change_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# frozen_string_literal: true
class EphemeraBoxChangeSet < Valhalla::ChangeSet
apply_workflow BoxWorkflow
validates :barcode, :box_number, :visibility, :rights_statement, presence: true
property :barcode, multiple: false, required: true
property :box_number, multiple: false, required: true
property :shipped_date, multiple: false, required: false
property :tracking_number, multiple: false, required: false
property :member_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)
property :member_of_collection_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)
property :visibility, multiple: false, default: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
property :read_groups, multiple: true, required: false
property :rights_statement, multiple: false, required: true, default: "http://rightsstatements.org/vocab/NKC/1.0/", type: ::Types::URI
property :rights_note, multiple: false, required: false
delegate :human_readable_type, to: :model
validate :barcode_valid?

def barcode_valid?
# return if barcode.present? && barcode.first.match(/^\d+{14}$/)
return if Barcode.new(Array.wrap(barcode).first).valid?
errors.add(:barcode, 'has an invalid checkdigit')
end

def primary_terms
[
:barcode,
:box_number,
:shipped_date,
:tracking_number,
:member_of_collection_ids,
:append_id
]
end

def visibility=(visibility)
super.tap do |_result|
case visibility
when Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
self.read_groups = [Hydra::AccessControls::AccessRight::PERMISSION_TEXT_VALUE_PUBLIC]
when Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED
self.read_groups = [Hydra::AccessControls::AccessRight::PERMISSION_TEXT_VALUE_AUTHENTICATED]
when Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE
self.read_groups = []
end
end
end
end
9 changes: 9 additions & 0 deletions app/change_sets/ephemera_field_change_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
# frozen_string_literal: true
class EphemeraFieldChangeSet < Valkyrie::ChangeSet
validates :name, presence: true
property :name, multiple: false

def primary_terms
[:name]
end
end
83 changes: 83 additions & 0 deletions app/change_sets/ephemera_folder_change_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# frozen_string_literal: true
class EphemeraFolderChangeSet < Valhalla::ChangeSet
apply_workflow(FolderWorkflow)
validates :barcode, :folder_number, :title, :language, :genre, :width, :height, :page_count, :visibility, :rights_statement, presence: true
validates_with StateValidator
property :barcode, multiple: false, required: true
property :folder_number, multiple: false, required: true
property :title, multiple: false, required: true
property :sort_title, required: false
property :alternative_title, multiple: true, required: false
property :language, multiple: true, required: true
property :genre, multiple: false, required: true
property :width, multiple: false, required: true
property :height, multiple: false, required: true
property :page_count, multiple: false, required: true
property :series, multiple: false, required: false
property :creator, required: false
property :contributor, multiple: true, required: false
property :publisher, multiple: true, required: false
property :geographic_origin, required: false
property :subject, multiple: true, required: false
property :geo_subject, multiple: true, required: false
property :description, required: false
property :date_created, required: false
property :dspace_url, required: false
property :source_url, required: false
property :rights_statement, multiple: false, required: true, default: "http://rightsstatements.org/vocab/NKC/1.0/", type: ::Types::URI
property :rights_note, multiple: false, required: false
property :thumbnail_id, multiple: false, required: false, type: Valkyrie::Types::ID
property :member_of_collection_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)
property :read_groups, multiple: true, required: false
property :files, virtual: true, multiple: true, required: false
property :pending_uploads, multiple: true, required: false

property :start_canvas, required: false
property :viewing_direction, required: false
property :viewing_hint, multiple: false, required: false, default: "individuals"

property :visibility, multiple: false, default: Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC

delegate :human_readable_type, to: :model

def primary_terms
[
:barcode,
:folder_number,
:title,
:sort_title,
:alternative_title,
:language,
:genre,
:width,
:height,
:page_count,
:rights_statement,
:series,
:creator,
:contributor,
:publisher,
:geographic_origin,
:subject,
:geo_subject,
:description,
:date_created,
:dspace_url,
:source_url,
:append_id
]
end

def visibility=(visibility)
super.tap do |_result|
case visibility
when Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PUBLIC
self.read_groups = [Hydra::AccessControls::AccessRight::PERMISSION_TEXT_VALUE_PUBLIC]
when Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_AUTHENTICATED
self.read_groups = [Hydra::AccessControls::AccessRight::PERMISSION_TEXT_VALUE_AUTHENTICATED]
when Hydra::AccessControls::AccessRight::VISIBILITY_TEXT_VALUE_PRIVATE
self.read_groups = []
end
end
end
end
10 changes: 10 additions & 0 deletions app/change_sets/ephemera_project_change_set.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# frozen_string_literal: true
class EphemeraProjectChangeSet < Valkyrie::ChangeSet
validates :title, presence: true
property :title, multiple: false
property :member_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)

def primary_terms
[:title]
end
end
45 changes: 2 additions & 43 deletions app/change_sets/scanned_resource_change_set.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# frozen_string_literal: true
class ScannedResourceChangeSet < Valkyrie::ChangeSet
class ScannedResourceChangeSet < Valhalla::ChangeSet
apply_workflow(BookWorkflow)
delegate :human_readable_type, to: :model
property :title, multiple: true, required: true, default: []
property :source_metadata_identifier, required: true, multiple: false
Expand All @@ -18,16 +19,13 @@ class ScannedResourceChangeSet < Valkyrie::ChangeSet
property :start_canvas, multiple: false, type: Valkyrie::Types::ID
property :member_of_collection_ids, multiple: true, required: false, type: Types::Strict::Array.member(Valkyrie::Types::ID)
property :logical_structure, multiple: true, required: false, type: Types::Strict::Array.member(Structure), default: [Structure.new(label: "Logical", nodes: [])]
property :state, multiple: false, required: true, default: BookWorkflow.aasm.initial_state.to_s
property :read_groups, multiple: true, required: false
property :workflow_note, multiple: true, required: false, default: []
property :file_metadata, multiple: true, required: false, default: []
# Virtual Attributes
property :refresh_remote_metadata, virtual: true, multiple: false
property :files, virtual: true, multiple: true, required: false
property :pending_uploads, multiple: true, required: false
# Necessary for SimpleForm to show the nested record.
property :new_workflow_note_attributes, virtual: true

validates_with StateValidator
validates_with ViewingDirectionValidator
Expand All @@ -52,18 +50,6 @@ def primary_terms
]
end

def new_workflow_note_attributes=(attributes)
return unless new_workflow_note.validate(attributes)
new_workflow_note.sync
workflow_note << new_workflow_note.model
end

# Default is set this way so that the WorkflowNoteChangeSet validations don't
# show in the nested form.
def new_workflow_note
@new_workflow_note ||= DynamicChangeSet.new(WorkflowNote.new)
end

def visibility=(visibility)
super.tap do |_result|
case visibility
Expand Down Expand Up @@ -93,31 +79,4 @@ def source_metadata_identifier_valid
def apply_remote_metadata?
source_metadata_identifier.present? && (!persisted? || refresh_remote_metadata == "1")
end

def workflow
workflow_class.new(state.first)
end

def workflow_class
BookWorkflow
end

def state_changed?
# conditional assignment makes this true if it has ever been true, to allow seeing the change after sync
@state_changed ||= changed?(:state) && !old_state.nil? && old_state != new_state
end

def new_state
Array.wrap(state).first
end

def old_state
Array.wrap(model.state).first
end

def prepopulate!
super.tap do
@_changes = Disposable::Twin::Changed::Changes.new
end
end
end
18 changes: 18 additions & 0 deletions app/controllers/ephemera_boxes_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true
class EphemeraBoxesController < ApplicationController
include Valhalla::ResourceController
include TokenAuth
self.change_set_class = DynamicChangeSet
self.resource_class = EphemeraBox
self.change_set_persister = ::PlumChangeSetPersister.new(
metadata_adapter: Valkyrie::MetadataAdapter.find(:indexing_persister),
storage_adapter: Valkyrie.config.storage_adapter
)
before_action :load_collections, only: [:new, :edit]

private

def load_collections
@collections = query_service.find_all_of_model(model: Collection).map(&:decorate)
end
end
11 changes: 11 additions & 0 deletions app/controllers/ephemera_fields_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# frozen_string_literal: true
class EphemeraFieldsController < ApplicationController
include Valhalla::ResourceController
include TokenAuth
self.change_set_class = DynamicChangeSet
self.resource_class = EphemeraField
self.change_set_persister = ::PlumChangeSetPersister.new(
metadata_adapter: Valkyrie::MetadataAdapter.find(:indexing_persister),
storage_adapter: Valkyrie.config.storage_adapter
)
end
Loading

0 comments on commit 00a2e31

Please sign in to comment.