(function () {
'use strict';
// Collection Item
angular.module('mohistory').component('collectionsItem', {
templateUrl: 'app/components/collections-item/collections-item.component.html',
controller: collectionsItemCtrl,
controllerAs: 'collectionsItem',
bindings: {
item: '<',
ead: '<',
visuallyHidden: '<',
a11yHidden: '<',
setVisuallyHidden: '<',
setA11yHidden: '<',
setFooterHidden: '<',
},
});
collectionsItemCtrl.$inject = ['searchFacets', 'configSeparated', 'currentEnvironment', 'keywordSearcher', '$transitions', '$rootScope'];
/**
* Display a collection item's details and, if applicable, its EAD data. Also manage
* the state of the viewer which is used to show items which have thumbnails.
* @memberof mohistory
* @name collectionsItem
* @ngdoc component
* @param {object} searchFacets Service which manages the UI-State and by extension the query string in the URL
* @param {object} configSeparated Object containing the API URLs
* @param {string} currentEnvironment What API URL configuration to use when making queries
* @param {object} keywordSearcher Service which wraps search related API calls
* @param {object} $transitions allows for registering hooks to preform action when certain UI-Router event occur
* @param {object} $rootScope Universal parent scope for the app
*/
function collectionsItemCtrl(searchFacets, configSeparated, currentEnvironment, keywordSearcher, $transitions, $rootScope) {
var vm = this;
/* ----- Variables ----- */
// Viewer
vm.page = 1;
vm.fullscreen = true;
vm.view = 'default';
vm.viewerOptions = {
default: {
code: 'defaultviewer/viewer.php?ID=',
extra: '',
},
universal: {
code: 'universalviewer/viewer.php?ID=',
extra: '',
},
zoom: {
code: 'seadragon/viewer.php?ID=',
extra: '',
},
scroll: {
code: 'iabookreader/viewer.php?ID=',
extra: '/mode/1up',
},
book: {
code: 'iabookreader/viewer.php?ID=',
extra: '/mode/2up',
},
tile: {
code: 'iabookreader/viewer.php?ID=',
extra: '/mode/thumb',
},
mirador: {
code: 'mirador/viewer.php?ID=',
extra: '',
}
};
// Copyright Information
vm.areRightsVisible = false;
vm.rights = {
'InC': {
fullStatement: 'IN COPYRIGHT',
statementParagraph: 'This Item is protected by copyright and/or related rights. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use. For other uses you need to obtain permission from the rights-holder(s).',
statementURI: 'http://rightsstatements.org/vocab/InC/1.0/',
},
'InC-OW-EU': {
fullStatement: 'IN COPYRIGHT - EU ORPHAN WORK',
statementParagraph: 'This Item has been identified as an orphan work in the country of first publication and in line with Directive 2012/28/EU of the European Parliament and of the Council of 25 October 2012 on certain permitted uses of orphan works. For this Item, either (a) no rights-holder(s) have been identified or (b) one or more rights-holder(s) have been identified but none have been located even though a diligent search for the rights-holder(s) has been conducted. The results of the diligent search are available in the EU Orphan Works Database. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use.',
statementURI: 'http://rightsstatements.org/vocab/InC-OW-EU/1.0/'
},
'InC-EDU': {
fullStatement: 'IN COPYRIGHT - EDUCATIONAL USE PERMITTED',
statementParagraph: 'This Item is protected by copyright and/or related rights. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use. In addition, no permission is required from the rights-holder(s) for educational uses. For other uses, you need to obtain permission from the rights-holder(s).',
statementURI: 'http://rightsstatements.org/vocab/InC-EDU/1.0/',
},
'InC-NC': {
fullStatement: 'IN COPYRIGHT - NON-COMMERCIAL USE PERMITTED',
statementParagraph: 'This Item is protected by copyright and/or related rights. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use. In addition, no permission is required from the rights-holder(s) for non-commercial uses. For other uses you need to obtain permission from the rights-holder(s).',
statementURI: 'http://rightsstatements.org/vocab/InC-NC/1.0/',
},
'InC-RUU': {
fullStatement: 'IN COPYRIGHT - RIGHTS-HOLDER(S) UNLOCATABLE OR UNIDENTIFIABLE',
statementParagraph: 'This Item is protected by copyright and/or related rights. However, for this Item, either (a) no rights-holder(s) have been identified or (b) one or more rights-holder(s) have been identified but none have been located. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use.',
statementURI: 'http://rightsstatements.org/vocab/InC-RUU/1.0/',
},
'NoC-CR': {
fullStatement: 'NO COPYRIGHT - CONTRACTUAL RESTRICTIONS',
statementParagraph: 'Use of this Item is not restricted by copyright and/or related rights. As part of the acquisition or digitization of this Item, the organization that has made the Item available is contractually required to limit the use of this Item. Limitations may include, but are not limited to, privacy issues, cultural protections, digitization agreements or donor agreements. Please refer to the organization that has made the Item available for more information.',
statementURI: 'http://rightsstatements.org/vocab/NoC-CR/1.0/',
},
'NoC-NC': {
fullStatement: 'NO COPYRIGHT - NON-COMMERCIAL USE ONLY',
statementParagraph: 'This object has been digitized in a public-private partnership. As part of this partnership, the partners have agreed to limit commercial uses of this digital representation of the object by third parties. You can, without permission, copy, modify, distribute, display, or perform the digital object, for non-commercial uses. For any other permissible uses, please review the terms and conditions of the organization that has made the item available.',
statementURI: 'http://rightsstatements.org/vocab/NoC-NC/1.0/',
},
'NoC-OKLR': {
fullStatement: 'NO COPYRIGHT - OTHER KNOWN LEGAL RESTRICTIONS',
statementParagraph: 'Use of this Item is not restricted by copyright and/or related rights. In one or more jurisdictions, laws other than copyright are known to impose restrictions on the use of this Item. Please refer to the organization that has made the Item available for more information.',
statementURI: 'http://rightsstatements.org/vocab/NoC-OKLR/1.0/',
},
'NoC-US': {
fullStatement: 'NO COPYRIGHT - UNITED STATES',
statementParagraph: 'The organization that has made the Item available believes that the Item is in the Public Domain under the laws of the United States, but a determination was not made as to its copyright status under the copyright laws of other countries. The Item may not be in the Public Domain under the laws of other countries. Please refer to the organization that has made the Item available for more information.',
statementURI: 'http://rightsstatements.org/vocab/NoC-US/1.0/',
},
'CNE': {
fullStatement: 'COPYRIGHT NOT EVALUATED',
statementParagraph: 'The copyright and related rights status of this Item has not been evaluated. Please refer to the organization that has made the Item available for more information. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use.',
statementURI: 'http://rightsstatements.org/vocab/CNE/1.0/',
},
'NKC': {
fullStatement: 'NO KNOWN COPYRIGHT',
statementParagraph: 'The organization that has made the Item available reasonably believes that the Item is not restricted by copyright or related rights, but a conclusive determination could not be made. Please refer to the organization that has made the Item available for more information. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use.',
statementURI: 'http://rightsstatements.org/vocab/NKC/1.0/',
},
'UND': {
fullStatement: 'COPYRIGHT UNDETERMINED',
statementParagraph: 'The copyright and related rights status of this Item has been reviewed by the organization that has made the Item available, but the organization was unable to make a conclusive determination as to the copyright status of the Item. Please refer to the organization that has made the Item available for more information. You are free to use this Item in any way that is permitted by the copyright and related rights legislation that applies to your use.',
statementURI: 'http://rightsstatements.org/vocab/UND/1.0/',
}
};
// Albers Boxes and Child List
vm.itemOwner = {};
vm.childName = '';
vm.container = '';
vm.childList = [];
vm.childListToShow = [];
vm.childListStep = 4;
vm.ISBusy = false;
vm.endOfCL = false;
vm.clTotalResults = 0;
vm.possibleOwners = {
'A': {
ownerLink: 'http://mohistory.org/research/documents-archives/',
owner: 'MHS Archives',
searchFacet: 'Archival Collections',
email: 'archives@mohistory.org',
phone: '(314) 746-4510',
},
'M': {
ownerLink: 'http://mohistory.org/research/multimedia/',
owner: 'MHS Moving Images and Sound Collection',
searchFacet: 'Moving Image and Sound Collection',
email: 'cmartinez@mohistory.org',
phone: '(314) 746-4585',
},
'L': {
ownerLink: 'http://mohistory.org/research/library/',
owner: 'MHS Library',
searchFacet: 'Library Collections',
email: 'library@mohistory.org',
phone: '(314) 746-4500',
},
'P': {
ownerLink: 'http://mohistory.org/research/documents-archives/',
owner: 'MHS Photographs and Prints Collection',
searchFacet: 'Photos and Prints Collections',
email: 'photo@mohistory.org',
phone: '(314) 746-4511',
},
'O': {
ownerLink: 'http://mohistory.org/research/objects-artifacts',
owner: 'MHS Objects Collection',
searchFacet: 'Objects Collection',
email: 'objects@mohistory.org',
phone: '(314) 746-4441',
},
'none': {
ownerLink: false,
owner: 'owner undefined',
searchFacet: false,
email: false,
phone: false,
}
};
// EAD
vm.eadText = false;
vm.eadTextAbove = false;
vm.eadTextBelow = false;
// PDFs
vm.collectionPDF = '';
vm.collectionLegacyPDF = '';
vm.collectionXML = '';
// For a few records
vm.multiFields = [];
// Downloads
vm.downloadPage = 0;
// UI-Router hook triggered when a transition succeeds
var uiOnSuccess = $transitions.onStart({}, function ($transition$) {
var stateName = $transition$.to().name;
var prevStateName = $transition$.from().name;
// Update infinite scroll when collection item changes
if (stateName !== prevStateName) {
$rootScope.$broadcast('item:changed');
}
});
/* ----- Function Bindings ----- */
vm.$onInit = onInit;
vm.$onDestroy = onDestroy;
vm.containerFinder = containerFinder;
vm.setView = setView;
vm.setFullscreen = setFullscreen;
vm.getViewerURL = getViewerURL;
vm.downloadPageChanger = downloadPageChanger;
vm.pageChanger = pageChanger;
vm.toggleRightsArea = toggleRightsArea;
vm.clNextResults = clNextResults;
vm.convertToString = convertToString;
/* ----- Function Definitions ----- */
/**
* Initialization code run every time the component is created, used to setup variables
* and to retrieve data from API.
* @function onInit
* @memberof collectionsItem
*/
function onInit() {
vm.page = searchFacets.getSearchFacets('page');
vm.downloadPage = vm.page;
vm.fullscreen = searchFacets.getSearchFacets('fullscreen');
vm.view = searchFacets.getSearchFacets('view');;
vm.collectionPDF = 'http://archiveserver.mohistory.org/pdf/' + vm.item.ids[0] + '.pdf';
vm.collectionLegacyPDF = 'http://archiveserver.mohistory.org/legacyPDFs/' + vm.item.ids[0] + '.pdf';
vm.collectionXML = 'http://archiveserver.mohistory.org/ead/' + vm.item.ids[0] + '_ead.xml';
/* ----- Uncomment below condition to turn EAD on ----- */
// if (vm.ead) {
// if (vm.ead.ead) {
// vm.eadText = true;
// vm.eadTextAbove = true;
// }
// if (vm.ead.ead && vm.ead.ead.archdesc.dsc) {
// vm.eadTextBelow = true;
// }
// }
// Determine containers via metadata
vm.containerFinder();
// Determine owner information
vm.itemOwner = vm.possibleOwners[vm.item.mimsyRecordType] || vm.possibleOwners['none'];
// If Record contains multifields, split them
// Example: resource:570197
if (vm.item.multifields) {
for (var keyVal in vm.item.multifields) {
vm.multiFields.push(vm.item.multifields[keyVal].split(':'));
}
}
// Retrieve the first set of records for the child list
keywordSearcher.getItemChildList(vm.item.itemID, 0).then(function (response) {
vm.childList = response.items;
if (typeof response.total !== 'number') {
response.total = Number(response.total.replace(/,/g, ""));
}
vm.clTotalResults = response.total;
if (vm.childList.length > vm.childListStep) {
vm.childListToShow = vm.childList.slice(0, vm.childListStep);
} else {
vm.childListToShow = vm.childList;
}
});
}
/**
* Clean up function called when a component is removed.
* @function onDestroy
* @memberof collectionsItem
*/
function onDestroy() {
// Deregister UI-Router hooks
uiOnSuccess();
}
/**
* Determine labels for the Albers Boxes based on metadata.
* @function containerFinder
* @memberof collectionsItem
*/
function containerFinder() {
var parentType = vm.item.wholePart;
var childType = vm.item.childCounts;
vm.childName = 'Item';
vm.container = parentType;
if (/Whole/.test(parentType)) {
vm.container = 'Item';
} else if (/Part/.test(parentType)) {
vm.container = 'Item';
}
if (vm.item.childCounts) {
var childString = String(Object.keys(childType));
// Default parent and child values directly from metadata
vm.childName = 'Item';
if (Object.keys(childType).length == 1) {
vm.childName = Object.keys(childType);
if (/Box/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("Box", "Boxe");
} else if (/box/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("box", "Boxe");
} else if (/Series/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("Series", "Serie");
} else if (/series/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("series", "Serie");
}
} else if (Object.keys(childType).length == 2) {
vm.childName = Object.keys(childType);
vm.childName = String(vm.childName).replace(",", "s and ");
if (/Box/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("Box", "Boxe");
} else if (/box/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("box", "Boxe");
} else if (/Series/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("Series", "Serie");
} else if (/series/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("series", "Serie");
}
}
// Special cases
if (/Job/.test(parentType)) {
vm.container = 'Job File';
}
if (/Job/.test(String(vm.childName))) {
vm.childName = String(vm.childName).replace("Job", "Job File");
}
if (/Series/.test(String(vm.childName)) && vm.item.childCounts['Series'] > 1) {
vm.childName = String(vm.childName).replace("Series", "Serie");
}
if (/Series/.test(String(vm.childName)) && vm.item.childCounts['Sub-Series'] > 1) {
vm.childName = String(vm.childName).replace("Series", "Serie");
}
// Correcting for plural boxes...
if (vm.childName == 'Box' && vm.item.childCounts['Box'] > 1) {
vm.childName = 'Boxe'
}
}
};
/**
* Set the current view type which effects how the item's data is
* displayed in the viewer.
* @function setView
* @memberof collectionItems
* @param {string} viewType What viewer to load. Valid values are 'default',
* 'zoom', 'scroll', 'book', and 'tile'
*/
function setView(viewType) {
vm.view = viewType;
searchFacets.addFacetToHash('view', vm.view);
}
/**
* Set the viewer to fullscreen mode and hide everything else on the page.
* @function setFullscreen
* @memberof collectionItems
*/
function setFullscreen() {
var isFullscreen = !vm.visuallyHidden;
vm.setVisuallyHidden(isFullscreen);
searchFacets.addFacetToHash('fullscreen', isFullscreen);
}
/**
* Generate the URL used to load the item viewer iframe.
* By putting the url in an array and ng-repeating we can force the iframe to reload.
* See: https://stackoverflow.com/questions/18718393/refreshing-iframe-contents-in-angularjs#answer-40389823
* @function getViewerURL
* @memberof collectionItems
* @return {array} An array with one string representing the viewer URL
*/
function getViewerURL() {
return [configSeparated[currentEnvironment].PLUGINS_PATH +
vm.viewerOptions[vm.view].code + vm.item.ids[0] + '#page/' +
vm.page + vm.viewerOptions[vm.view].extra
];
}
/**
* Updates the thumbnail shown in the download section.
* @function downloadPageChanger
* @memberof collectionsItem
* @param {string} direction 'forward' will advance the shown thumbnail by 1. 'back' will retreat the shown
* image by one.
*/
function downloadPageChanger(direction) {
if (direction === 'forward') {
vm.downloadPage = (vm.downloadPage + 1) > vm.item.mhs_images.length ? 1 : vm.downloadPage + 1;
} else if (direction === 'back') {
vm.downloadPage = (vm.downloadPage - 1) < 1 ? vm.item.mhs_images.length : vm.downloadPage - 1;
}
}
/**
* Updates the image shown in the viewer.
* @function pageChanger
* @memberof collectionsItem
* @param {string} direction 'forward' will advance the shown thumbnail by 1. 'back' will retreat the shown
* image by one.
*/
function pageChanger(direction) {
if (direction === 'forward') {
vm.page = (vm.page + 1) > vm.item.assetCount ? 1 : vm.page + 1;
} else if (direction === 'back') {
vm.page = (vm.page - 1) < 1 ? vm.item.assetCount : vm.page - 1;
}
searchFacets.addFacetToHash('page', vm.page);
}
/**
* Open or close the copyright information area.
* @function toggleRightsArea
* @memberof collectionsItem
*/
function toggleRightsArea() {
vm.areRightsVisible = !vm.areRightsVisible;
}
/**
* Manage infinite scrolling for the child list. Every API call retrieves 20 items. Every time
* this function is called it adds four elements to those shown. If there are no more elements
* in memory, then call the API again.
* @function clNextResults
* @memberof collectionsItem
*/
function clNextResults() {
if (vm.ISBusy || vm.endOfCL) {
return;
}
vm.ISBusy = true;
vm.setFooterHidden(true); // Hide the footer, because it interferes with the infinite scroll process
if ((vm.childListToShow.length + vm.childListStep) < vm.childList.length || vm.childList.length === vm.clTotalResults) {
// Add more elements from those stored in memory
vm.childListToShow = vm.childListToShow.concat(vm.childList.slice(vm.childListToShow.length, vm.childListToShow.length + vm.childListStep));
if (vm.childList.length === vm.clTotalResults && vm.childList.length === vm.childListToShow.length) {
// All elements have been scrolled through, so show the footer
vm.endOfCL = true;
vm.setFooterHidden(false);
}
vm.ISBusy = false;
} else if (vm.childList.length !== vm.clTotalResults) {
// Add more elements after querying the API for another batch
var diff = vm.childList.length - vm.childListToShow.length;
if (diff > 0) {
// Just in case the shown list isn't the same as the list stored in memory, add the last few elements
vm.childListToShow = vm.childListToShow.concat(vm.childList.slice(vm.childListToShow.length))
}
keywordSearcher.getItemChildList(vm.item.itemID, vm.childList.length - 1).then(function (response) {
if (response.items.length === 0) {
// API has confirmed the end of the list
vm.endOfCL = true;
vm.setFooterHidden(false);
} else {
// Add items from the API to those stored in memory
vm.childList = vm.childList.concat(response.items);
if (typeof response.total !== 'number') {
// Remove comma if the total is returned as a string
response.total = Number(response.total.replace(/,/g, ""));
}
vm.clTotalResults = response.total;
vm.childListToShow = vm.childListToShow.concat(vm.childList.slice(vm.childListToShow.length, diff))
}
vm.ISBusy = false;
});
} else {
// @note: not sure if this is necessary
// Fall back
vm.endOfCL = true;
vm.setFooterHidden(false);
vm.ISBusy = false;
}
}
/**
* Convert value to type string
* @function convertToString
* @memberof collectionsItem
* @param {number} value The value to be converted
* @return {string} The string version of value
*/
function convertToString(value) {
return String(value);
}
}
})();