Skip to content

Commit

Permalink
ANW-616 - adding a spawn component feature to accession record toolbar
Browse files Browse the repository at this point in the history
  • Loading branch information
Brian Hoffman committed Apr 27, 2022
1 parent 4cda3fe commit 75f06c5
Show file tree
Hide file tree
Showing 25 changed files with 770 additions and 61 deletions.
302 changes: 302 additions & 0 deletions frontend/app/assets/javascripts/archival_objects.crud.js
@@ -0,0 +1,302 @@
//= require agents.crud
//= require subjects.crud
//= require dates.crud
//= require notes.crud
//= require instances.crud
//= require lang_materials.crud
//= require deaccessions.crud
//= require subrecord.crud
//= require rights_statements.crud
//= require form

function SimpleLinkingModal(config) {
var self = this;
self.config = config;
self.page = 1;
self.currentSelected = undefined;
self.context_filter_term = [];
(config.context_filter_term || []).forEach((element, index) => {
self.context_filter_term.push(JSON.stringify(element));
});
self.config.label_plural = config.button_title;
self.$modal = AS.openCustomModal(
'linkResourceModal',
self.config.title,
AS.renderTemplate('linker_browsemodal_template', config),
'large',
{},
this
);
if (config.must_select) {
$('.modal-header a', self.$modal).hide();
}
self.$container = $('.linker-container', self.$modal);
self.reload_modal(self.config.url_html);
self.init_click_handlers();
self.init_radio_handlers();
}

SimpleLinkingModal.prototype.update_state_from_href = function (href) {
var self = this;
var requestParams = decodeURIComponent(href).split('?')[1];
requestParams = new URLSearchParams(requestParams);

if (requestParams.has('page')) {
self.page = new Number(requestParams.get('page'));
} else if (href == '#') {
self.page = 1;
}
if (requestParams.has('sort')) {
self.sort = requestParams.get('sort');
}
if (requestParams.has('filter_term[]')) {
self.filter_term = requestParams.get('filter_term[]');
}
};

SimpleLinkingModal.prototype.init_radio_handlers = function () {
var self = this;

// change selected
function clickRadioHandler(event) {
event.stopPropagation();
self.set_selected($(this).val());
}

this.$modal.on('click', '.table-search-results input', clickRadioHandler);
this.$modal.on('click', '.table-search-results tr', function (event) {
event.preventDefault();
$('input', $(this)).trigger('click');
});
};

SimpleLinkingModal.prototype.init_click_handlers = function () {
var self = this;

// update the browse table only from JSON endpoint
function jsonRefreshHandler(event) {
event.preventDefault();
self.update_state_from_href($(this).attr('href'));
self.reload_results_table();
}

self.$modal.on('click', '.table-search-results a', jsonRefreshHandler);
self.$modal.on('click', '.pagination a', jsonRefreshHandler);
self.$modal.on('click', '.search-listing-filter a', function (event) {
event.preventDefault();
var url = $(this).attr('href');
self.reload_modal(url);
});
self.$modal.on('click', '.search-filter button', function (event) {
event.preventDefault();
var url = self.config.url_html + '&q=' + $('#filter-text').val();
self.reload_modal(url);
});
self.$modal.on('click', '#addSelectedButton', function (event) {
event.preventDefault();
if (self.currentSelected) {
// closing this way to get proper focus back in main window
$('.modal-header a', self.$modal).trigger('click');
self.config.onLink(self.currentSelected);
}
return false;
});
};

SimpleLinkingModal.prototype.set_selected = function (uri) {
var self = this;
this.currentSelected = uri;
$('#addSelectedButton').removeClass('disabled');
$('tr.selected').removeClass('selected');
var $input = $(":input[value='" + uri + "']", self.$modal);
$input.closest('tr').addClass('selected');
};

SimpleLinkingModal.prototype.set_active_page = function (page) {
var self = this;
$('ul.pagination li', self.$modal).removeClass('active');
$($('ul.pagination li', self.$modal)[page]).addClass('active');
};

SimpleLinkingModal.prototype.set_pagination_size = function (last_page) {
var self = this;
$('ul.pagination li', self.$modal)
.toArray()
.forEach((element, index) => {
if (index > last_page) {
$(element).hide();
} else {
$(element).show();
}
});
};

SimpleLinkingModal.prototype.set_pagination_summary = function (
offset_first,
offset_last,
total_hits
) {
var self = this;
$('.record-pane strong:first', self.$modal).html(offset_first);
$('.record-pane strong:nth(1)', self.$modal).html(offset_last);
$('.record-pane strong:nth(2)', self.$modal).html(total_hits);
};

// update the results table when it is sorted or paged
SimpleLinkingModal.prototype.reload_results_table = function () {
var self = this;
$.ajax({
url: self.config.url_json,
type: 'GET',
dataType: 'json',
data: {
page: self.page,
sort: self.sort,
type: self.config.types,
filter_term: self.filter_term,
linker: true,
multiplicity: 1,
},
success: function (searchData) {
searchData['config'] = self.config;
// update pagination
self.set_pagination_summary(
searchData.search_data.offset_first,
searchData.search_data.offset_last,
searchData.search_data.total_hits
);
self.set_pagination_size(searchData.search_data.last_page);
self.set_active_page(searchData.search_data.this_page);
// update results table
var rows = '';
searchData.search_data.results.forEach(item => {
rows += AS.renderTemplate('linker_browse_row_template', item);
});
$('#tabledSearchResults tbody').html(rows);
// self.init_radio_handlers();
if (self.currentSelected) {
var $input = $(
"input[value='" + self.currentSelected + "']",
self.$modal
);
$input.trigger('click');
}
},
error: function (jqXHR, textStatus, errorThrown) {},
});
};

// update the entire modal with a new html document
SimpleLinkingModal.prototype.reload_modal = function (url) {
var self = this;
self.currentSelected = undefined;
$('#addSelectedButton').addClass('disabled');
var _data = {
type: self.config.types,
context_filter_term: self.context_filter_term || [],
linker: true,
multiplicity: 1,
hide_sort_options: true,
hide_csv_download: true,
};

$.ajax({
url: url,
type: 'GET',
dataType: 'html',
data: _data,
success: function (html) {
self.$container.html(html);
},
});
};

// pops up serial modals to ensure resource and parent are determined
function validateResourceAndParent() {
var $resourceInput = $('#archival_object_form').find(
'input[name="archival_object[resource]"]'
);
var $parentInput = $('#archival_object_form').find(
'input[name="archival_object[parent]"]'
);
if ($resourceInput.val() !== undefined && $resourceInput.val().length < 1) {
$('#archival_object_form')
.find('.save-changes :submit')
.addClass('disabled')
.attr('disabled', 'disabled');
// launch modal for selecting the resource
new SimpleLinkingModal({
url_html: $resourceInput.data('browse-url-html'),
url_json: $resourceInput.data('browse-url-json'),
title: $resourceInput.data('modal-title'),
primary_button_text: $resourceInput.data('modal-title'),
types: ['resource'],
linker: true, //?
multiplicity: 1,
must_select: true,
onLink: function (resource_uri) {
$resourceInput.attr('name', 'archival_object[resource][ref]');
$resourceInput.val(resource_uri);
$('#archival_object_form')
.find(':submit')
.removeClass('disabled')
.removeAttr('disabled');
validateResourceAndParent();
},
});
} else if (
$parentInput.val() !== undefined &&
$parentInput.val().length < 1
) {
// now do same thing for parent
var $resourceURI = $('#archival_object_form')
.find('input[name="archival_object[resource][ref]"]')
.val();
new SimpleLinkingModal({
url_html: $parentInput.data('browse-url-html'),
url_json: $parentInput.data('browse-url-json'),
title: $parentInput.data('modal-title'),
primary_button_text: $parentInput.data('modal-title'),
cancel_button_text: $parentInput.data('leave-empty'),
types: ['archival_object'],
context_filter_term: [
{
resource: $resourceURI,
},
],
linker: true,
multiplicity: 1,
onLink: function (parent_uri) {
$parentInput.attr('name', 'archival_object[parent][ref]');
$parentInput.val(parent_uri);
validateResourceAndParent();
},
});
}
}

$(function () {
$('#archival_object_form').on(
'click',
'.select-resource :submit',
function (event) {
event.preventDefault();
// reset everything when user clicks "select resource"
$('#archival_object_form')
.find('input[name="archival_object[resource][ref]"]')
.val('');
$('#archival_object_form')
.find('input[name="archival_object[resource][ref]"]')
.attr('name', 'archival_object[resource]');
$('#archival_object_form')
.find('input[name="archival_object[parent][ref]"]')
.val('');
$('#archival_object_form')
.find('input[name="archival_object[parent][ref]"]')
.attr('name', 'archival_object[parent]');
validateResourceAndParent();
}
);

validateResourceAndParent();
});
4 changes: 4 additions & 0 deletions frontend/app/assets/stylesheets/archivesspace/icons.less
Expand Up @@ -13,6 +13,10 @@

margin: 0 2px 0 0;

&.icon-archival_object::before {
content: '\e921';
}

&.icon-resource::before {
content: '\ea71';
}
Expand Down
5 changes: 3 additions & 2 deletions frontend/app/controllers/application_controller.rb
Expand Up @@ -701,12 +701,13 @@ def cleanup_params_for_schema(params_hash, schema)
end

def params_for_backend_search
params_for_search = params.select {|k, v| ["page", "q", "aq", "type", "sort", "exclude", "filter_term", "fields"].include?(k) and not v.blank?}
backend_search_params = ["page", "q", "aq", "type", "sort", "exclude", "filter_term", "fields"]
params_for_search = params.select {|k, v| backend_search_params.include?(k) and not v.blank?}

params_for_search["page"] ||= 1

if params_for_search["type"]
params_for_search["type[]"] = Array(params_for_search["type"]).reject {|v| v.blank?}
params_for_search["type[]"] = Array(params_for_search["type"]).reject {|v| v.blank?}.uniq
params_for_search.delete("type")
end

Expand Down
35 changes: 27 additions & 8 deletions frontend/app/controllers/archival_objects_controller.rb
Expand Up @@ -9,12 +9,21 @@ class ArchivalObjectsController < ApplicationController


def new
@archival_object = JSONModel(:archival_object).new._always_valid!
@archival_object.parent = {'ref' => JSONModel(:archival_object).uri_for(params[:archival_object_id])} if params.has_key?(:archival_object_id)
@archival_object.resource = {'ref' => JSONModel(:resource).uri_for(params[:resource_id])} if params.has_key?(:resource_id)
@archival_object = ArchivalObject.new._always_valid!
@archival_object.parent = {'ref' => ArchivalObject.uri_for(params[:archival_object_id])} if params.has_key?(:archival_object_id)
@archival_object.resource = {'ref' => Resource.uri_for(params[:resource_id])} if params.has_key?(:resource_id)
@archival_object.position = params[:position]

if user_prefs['default_values']
if params[:accession_id]
acc = Accession.find(params[:accession_id], find_opts)

if acc
@archival_object.populate_from_accession(acc)
flash.now[:info] = I18n.t("archival_object._frontend.messages.spawned", JSONModelI18nWrapper.new(:accession => acc).enable_parse_mixed_content!(url_for(:root)))
flash[:spawned_from_accession] = acc.id
end

elsif user_prefs['default_values']
defaults = DefaultValues.get 'archival_object'

@archival_object.update(defaults.values) if defaults
Expand Down Expand Up @@ -43,7 +52,13 @@ def edit
def create
handle_crud(:instance => :archival_object,
:find_opts => find_opts,
:on_invalid => ->() { render_aspace_partial :partial => "new_inline" },
:on_invalid => ->() {
if inline?
render_aspace_partial :partial => "new_inline"
else
render action: :new
end
},
:on_valid => ->(id) {

success_message = @archival_object.parent ?
Expand All @@ -67,9 +82,13 @@ def create
flash.now[:warning] = I18n.t("slug.autogen_disabled")
end
end

render_aspace_partial :partial => "archival_objects/edit_inline"

if inline?
render_aspace_partial :partial => "archival_objects/edit_inline"
else
id = ArchivalObject.id_for(@archival_object.uri)
resource_id = Resource.id_for(@archival_object.resource['ref'])
redirect_to controller: :resources, action: :edit, id: resource_id, anchor: "tree::archival_object_#{id}"
end
})
end

Expand Down

0 comments on commit 75f06c5

Please sign in to comment.