NIHVIVO-2343 First shot at the Manage Proxies page.
This commit is contained in:
parent
23329bd5fc
commit
d1ecaccc5b
12 changed files with 604 additions and 5 deletions
|
@ -38,6 +38,7 @@ public abstract class AbstractPageHandler {
|
||||||
protected final VitroRequest vreq;
|
protected final VitroRequest vreq;
|
||||||
protected final ServletContext ctx;
|
protected final ServletContext ctx;
|
||||||
protected final OntModel userAccountsModel;
|
protected final OntModel userAccountsModel;
|
||||||
|
protected final OntModel unionModel;
|
||||||
protected final UserAccountsDao userAccountsDao;
|
protected final UserAccountsDao userAccountsDao;
|
||||||
protected final VClassDao vclassDao;
|
protected final VClassDao vclassDao;
|
||||||
protected final IndividualDao indDao;
|
protected final IndividualDao indDao;
|
||||||
|
@ -48,8 +49,9 @@ public abstract class AbstractPageHandler {
|
||||||
this.vreq = vreq;
|
this.vreq = vreq;
|
||||||
this.ctx = vreq.getSession().getServletContext();
|
this.ctx = vreq.getSession().getServletContext();
|
||||||
|
|
||||||
OntModelSelector oms = ModelContext.getBaseOntModelSelector(ctx);
|
OntModelSelector oms = ModelContext.getUnionOntModelSelector(ctx);
|
||||||
userAccountsModel = oms.getUserAccountsModel();
|
userAccountsModel = oms.getUserAccountsModel();
|
||||||
|
unionModel = oms.getFullModel();
|
||||||
|
|
||||||
WebappDaoFactory wdf = (WebappDaoFactory) this.ctx
|
WebappDaoFactory wdf = (WebappDaoFactory) this.ctx
|
||||||
.getAttribute("webappDaoFactory");
|
.getAttribute("webappDaoFactory");
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.Actions;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageProxies;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.FreemarkerHttpServlet;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parcel out the different actions required of the ManageProxies GUI.
|
||||||
|
*/
|
||||||
|
public class ManageProxiesController extends FreemarkerHttpServlet {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(ManageProxiesController.class);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Actions requiredActions(VitroRequest vreq) {
|
||||||
|
return new Actions(new ManageProxies());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected ResponseValues processRequest(VitroRequest vreq) {
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
dumpRequestParameters(vreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
String action = vreq.getPathInfo();
|
||||||
|
log.debug("action = '" + action + "'");
|
||||||
|
|
||||||
|
return handleListRequest(vreq);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ResponseValues handleListRequest(VitroRequest vreq) {
|
||||||
|
ManageProxiesListPage page = new ManageProxiesListPage(vreq);
|
||||||
|
return page.showPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,166 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
import static edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.DEFAULT_RELATIONSHIPS_PER_PAGE;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.AbstractPageHandler;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelectionCriteria.ProxyRelationshipView;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ProxyRelationshipSelector.Context;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.UrlBuilder;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.ResponseValues;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.controller.freemarker.responsevalues.TemplateResponseValues;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO
|
||||||
|
*/
|
||||||
|
public class ManageProxiesListPage extends AbstractPageHandler {
|
||||||
|
private static final Log log = LogFactory
|
||||||
|
.getLog(ManageProxiesListPage.class);
|
||||||
|
|
||||||
|
public static final String PARAMETER_RELATIONSHIPS_PER_PAGE = "relationshipsPerPage";
|
||||||
|
public static final String PARAMETER_PAGE_INDEX = "pageIndex";
|
||||||
|
public static final String PARAMETER_VIEW_TYPE = "viewType";
|
||||||
|
public static final String PARAMETER_SEARCH_TERM = "searchTerm";
|
||||||
|
|
||||||
|
private static final String TEMPLATE_NAME = "manageProxies-list.ftl";
|
||||||
|
|
||||||
|
private static final String DEFAULT_IMAGE_URL = UrlBuilder
|
||||||
|
.getUrl("/images/placeholders/person.thumbnail.jpg");
|
||||||
|
|
||||||
|
private final Context selectorContext;
|
||||||
|
|
||||||
|
private ProxyRelationshipSelectionCriteria criteria = ProxyRelationshipSelectionCriteria.DEFAULT_CRITERIA;
|
||||||
|
|
||||||
|
public ManageProxiesListPage(VitroRequest vreq) {
|
||||||
|
super(vreq);
|
||||||
|
|
||||||
|
selectorContext = new Context(userAccountsModel, unionModel,
|
||||||
|
getMatchingProperty());
|
||||||
|
parseParameters();
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMatchingProperty() {
|
||||||
|
return ConfigurationProperties.getBean(vreq).getProperty(
|
||||||
|
"selfEditing.idMatchingProperty", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build the criteria from the request parameters.
|
||||||
|
*/
|
||||||
|
private void parseParameters() {
|
||||||
|
int relationshipsPerPage = getIntegerParameter(
|
||||||
|
PARAMETER_RELATIONSHIPS_PER_PAGE,
|
||||||
|
DEFAULT_RELATIONSHIPS_PER_PAGE);
|
||||||
|
int pageIndex = getIntegerParameter(PARAMETER_PAGE_INDEX, 1);
|
||||||
|
ProxyRelationshipView viewType = ProxyRelationshipView.fromKeyword(vreq
|
||||||
|
.getParameter(PARAMETER_VIEW_TYPE));
|
||||||
|
String searchTerm = getStringParameter(PARAMETER_SEARCH_TERM, "");
|
||||||
|
|
||||||
|
criteria = new ProxyRelationshipSelectionCriteria(relationshipsPerPage,
|
||||||
|
pageIndex, viewType, searchTerm);
|
||||||
|
|
||||||
|
log.debug("selection criteria is: " + criteria);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResponseValues showPage() {
|
||||||
|
ProxyRelationshipSelection selection = ProxyRelationshipSelector
|
||||||
|
.select(selectorContext, criteria);
|
||||||
|
Map<String, Object> body = buildTemplateBodyMap(selection);
|
||||||
|
return new TemplateResponseValues(TEMPLATE_NAME, body);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Object> buildTemplateBodyMap(
|
||||||
|
ProxyRelationshipSelection selection) {
|
||||||
|
Map<String, Object> body = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
body.put("relationshipsPerPage", criteria.getRelationshipsPerPage());
|
||||||
|
body.put("pageIndex", criteria.getPageIndex());
|
||||||
|
body.put("viewType", criteria.getViewBy());
|
||||||
|
body.put("searchTerm", criteria.getSearchTerm());
|
||||||
|
|
||||||
|
body.put("relationships", wrapProxyRelationships(selection));
|
||||||
|
body.put("total", selection.getTotalResultCount());
|
||||||
|
body.put("page", buildPageMap(selection));
|
||||||
|
|
||||||
|
body.put("matchingProperty", getMatchingProperty());
|
||||||
|
|
||||||
|
body.put("formUrls", buildUrlsMap());
|
||||||
|
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProxyRelationship> wrapProxyRelationships(
|
||||||
|
ProxyRelationshipSelection selection) {
|
||||||
|
List<ProxyRelationship> wrapped = new ArrayList<ProxyRelationship>();
|
||||||
|
for (ProxyRelationship r : selection.getProxyRelationships()) {
|
||||||
|
wrapped.add(new ProxyRelationship(wrapItemList(r.getProxyInfos()),
|
||||||
|
wrapItemList(r.getProfileInfos())));
|
||||||
|
}
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ProxyItemInfo> wrapItemList(List<ProxyItemInfo> items) {
|
||||||
|
List<ProxyItemInfo> wrapped = new ArrayList<ProxyItemInfo>();
|
||||||
|
for (ProxyItemInfo item : items) {
|
||||||
|
wrapped.add(wrapItem(item));
|
||||||
|
}
|
||||||
|
return wrapped;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ProxyItemInfo wrapItem(ProxyItemInfo item) {
|
||||||
|
if (item.getImageUrl().isEmpty()) {
|
||||||
|
return new ProxyItemInfo(item.getUri(), item.getLabel(),
|
||||||
|
item.getClassLabel(), DEFAULT_IMAGE_URL);
|
||||||
|
} else {
|
||||||
|
return new ProxyItemInfo(item.getUri(), item.getLabel(),
|
||||||
|
item.getClassLabel(), UrlBuilder.getUrl(item.getImageUrl()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, Integer> buildPageMap(
|
||||||
|
ProxyRelationshipSelection selection) {
|
||||||
|
int currentPage = selection.getCriteria().getPageIndex();
|
||||||
|
|
||||||
|
float pageCount = ((float) selection.getTotalResultCount())
|
||||||
|
/ selection.getCriteria().getRelationshipsPerPage();
|
||||||
|
int lastPage = (int) Math.ceil(pageCount);
|
||||||
|
|
||||||
|
Map<String, Integer> map = new HashMap<String, Integer>();
|
||||||
|
|
||||||
|
map.put("current", currentPage);
|
||||||
|
map.put("first", 1);
|
||||||
|
map.put("last", lastPage);
|
||||||
|
|
||||||
|
if (currentPage < lastPage) {
|
||||||
|
map.put("next", currentPage + 1);
|
||||||
|
}
|
||||||
|
if (currentPage > 1) {
|
||||||
|
map.put("previous", currentPage - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Map<String, String> buildUrlsMap() {
|
||||||
|
Map<String, String> map = new HashMap<String, String>();
|
||||||
|
|
||||||
|
map.put("list", UrlBuilder.getUrl("/manageProxies/list"));
|
||||||
|
map.put("edit", UrlBuilder.getUrl("/manageProxies/edit"));
|
||||||
|
map.put("sparqlQueryAjax", UrlBuilder.getUrl("/ajax/sparqlQuery"));
|
||||||
|
map.put("defaultImageUrl", DEFAULT_IMAGE_URL);
|
||||||
|
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
package edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* On what basis are we selecting proxy relationships?
|
* On what basis are we selecting proxy relationships?
|
||||||
*
|
*
|
||||||
|
@ -23,6 +24,21 @@ public class ProxyRelationshipSelectionCriteria {
|
||||||
BY_PROXY, BY_PROFILE;
|
BY_PROXY, BY_PROFILE;
|
||||||
|
|
||||||
public static ProxyRelationshipView DEFAULT_VIEW = BY_PROXY;
|
public static ProxyRelationshipView DEFAULT_VIEW = BY_PROXY;
|
||||||
|
|
||||||
|
public static ProxyRelationshipView fromKeyword(String keyword) {
|
||||||
|
if (keyword == null) {
|
||||||
|
return DEFAULT_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ProxyRelationshipView v : ProxyRelationshipView.values()) {
|
||||||
|
if (v.toString().equals(keyword)) {
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return DEFAULT_VIEW;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** How many relationships should we bring back, at most? */
|
/** How many relationships should we bring back, at most? */
|
||||||
|
|
|
@ -21,6 +21,7 @@ import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditIndivi
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditOntology;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditSiteInformation;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.EditSiteInformation;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageMenus;
|
||||||
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageOwnProxies;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.ManageUserAccounts;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.SeeSiteAdminPage;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.SeeSiteAdminPage;
|
||||||
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.SeeStartupStatus;
|
import edu.cornell.mannlib.vitro.webapp.auth.requestedAction.usepages.SeeStartupStatus;
|
||||||
|
@ -131,6 +132,10 @@ public class BaseSiteAdminController extends FreemarkerHttpServlet {
|
||||||
data.put("userAccounts", UrlBuilder.getUrl("/accountsAdmin"));
|
data.put("userAccounts", UrlBuilder.getUrl("/accountsAdmin"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (PolicyHelper.isAuthorizedForActions(vreq, new ManageOwnProxies())) {
|
||||||
|
data.put("manageProxies", UrlBuilder.getUrl("/manageProxies"));
|
||||||
|
}
|
||||||
|
|
||||||
if (PolicyHelper.isAuthorizedForActions(vreq, new EditSiteInformation())) {
|
if (PolicyHelper.isAuthorizedForActions(vreq, new EditSiteInformation())) {
|
||||||
data.put("siteInfo", UrlBuilder.getUrl("/editForm", "controller", "ApplicationBean"));
|
data.put("siteInfo", UrlBuilder.getUrl("/editForm", "controller", "ApplicationBean"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -657,6 +657,15 @@
|
||||||
<url-pattern>/accounts/*</url-pattern>
|
<url-pattern>/accounts/*</url-pattern>
|
||||||
</servlet-mapping>
|
</servlet-mapping>
|
||||||
|
|
||||||
|
<servlet>
|
||||||
|
<servlet-name>ManageProxies</servlet-name>
|
||||||
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.accounts.manageproxies.ManageProxiesController</servlet-class>
|
||||||
|
</servlet>
|
||||||
|
<servlet-mapping>
|
||||||
|
<servlet-name>ManageProxies</servlet-name>
|
||||||
|
<url-pattern>/manageProxies/*</url-pattern>
|
||||||
|
</servlet-mapping>
|
||||||
|
|
||||||
<servlet>
|
<servlet>
|
||||||
<servlet-name>ShowAuth</servlet-name>
|
<servlet-name>ShowAuth</servlet-name>
|
||||||
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.admin.ShowAuthController</servlet-class>
|
<servlet-class>edu.cornell.mannlib.vitro.webapp.controller.admin.ShowAuthController</servlet-class>
|
||||||
|
|
|
@ -4,6 +4,72 @@
|
||||||
* A collection of building blocks for the proxy-management UI.
|
* A collection of building blocks for the proxy-management UI.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* itemElement
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Display information about an entity according to the template. The entity
|
||||||
|
* can be either:
|
||||||
|
* a profile -- Individual to be edited.
|
||||||
|
* a proxy -- User Account to do the editing, optionally with info from a
|
||||||
|
* profile associated with that individual.
|
||||||
|
*
|
||||||
|
* You provide:
|
||||||
|
* template -- the HTML text that determines how the element should look.
|
||||||
|
* The template must be a single HTML element, which may contain
|
||||||
|
* any number of sub-elements. It needs to have a single outer
|
||||||
|
* wrapper, however.
|
||||||
|
* uri, label, classLabel, imageUrl -- as described below
|
||||||
|
* remove -- a function that we can call when the user clicks on the remove
|
||||||
|
* link or button. We will pass a reference to this struct.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* The template must inlude a link or button with attribute templatePart="remove"
|
||||||
|
*
|
||||||
|
* The template may include tokens to be replaced, from the following:
|
||||||
|
* %uri% -- the URI of the individual being displayed
|
||||||
|
* %label& -- the label of the individual.
|
||||||
|
* %classLabel% -- the label of the most specific class of the individual.
|
||||||
|
* %imageUrl% -- the URL that will fetch the image of the individual,
|
||||||
|
* or a placeholder image.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* This relies on magic names for the styles:
|
||||||
|
* existingProxyItem -- for an item that was present when the page was loaded
|
||||||
|
* newProxyItem -- for an item that was added since the page was loaded
|
||||||
|
* removedProxyItem -- added to an item when the "remove" link is cheked.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
function itemElement(template, uri, label, classLabel, imageUrl, removeInfo) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.uri = uri;
|
||||||
|
this.label = label;
|
||||||
|
this.classLabel = classLabel;
|
||||||
|
this.imageUrl = (imageUrl) ? imageUrl : imageUrl="../images/placeholders/person.thumbnail.jpg";
|
||||||
|
this.removeInfo = removeInfo;
|
||||||
|
|
||||||
|
this.toString = function() {
|
||||||
|
return "proxyInfoElement: " + content;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.element = function() {
|
||||||
|
var content = template.replace(/%uri%/g, this.uri)
|
||||||
|
.replace(/%label%/g, this.label)
|
||||||
|
.replace(/%classLabel%/g, this.classLabel)
|
||||||
|
.replace(/%imageUrl%/g, this.imageUrl);
|
||||||
|
|
||||||
|
var element = $(content);
|
||||||
|
element.addClass("proxyInfoElement");
|
||||||
|
|
||||||
|
var removeLink = $("[templatePart='remove']", element).first();
|
||||||
|
removeLink.click(function(event) {
|
||||||
|
self.removeInfo(self);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ----------------------------------------------------------------------------
|
* ----------------------------------------------------------------------------
|
||||||
* proxyInfoElement
|
* proxyInfoElement
|
||||||
|
@ -53,8 +119,6 @@ function proxyInfoElement(template, uri, label, classLabel, imageUrl, removeInfo
|
||||||
.replace(/%classLabel%/g, this.classLabel)
|
.replace(/%classLabel%/g, this.classLabel)
|
||||||
.replace(/%imageUrl%/g, this.imageUrl);
|
.replace(/%imageUrl%/g, this.imageUrl);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
var element = $("<div class='proxyInfoElement' name='proxyInfoElement'>" + content + "</div>");
|
var element = $("<div class='proxyInfoElement' name='proxyInfoElement'>" + content + "</div>");
|
||||||
|
|
||||||
var removeLink = $("[templatePart='remove']", element).first();
|
var removeLink = $("[templatePart='remove']", element).first();
|
||||||
|
|
180
webapp/web/js/account/accountProxyItemsPanel.js
Normal file
180
webapp/web/js/account/accountProxyItemsPanel.js
Normal file
|
@ -0,0 +1,180 @@
|
||||||
|
/* $This file is distributed under the terms of the license in /doc/license.txt$ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* proxyItemsPanel
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* Display an AJAX-enabled list of proxy-related items (either proxies or
|
||||||
|
* profiles).
|
||||||
|
*
|
||||||
|
* The list may start out with a population of items. items may be added by
|
||||||
|
* selecting them in the auto-complete box. Items may be removed by clicking
|
||||||
|
* the "remove" link next to that item.
|
||||||
|
*
|
||||||
|
* A hidden field will hold the URI for each item, so when the form is submitted,
|
||||||
|
* the controller can determine the list of items.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
* You provide:
|
||||||
|
* p -- the DOM element that contains the template and the data.
|
||||||
|
* It also contains the autocomplete field.
|
||||||
|
* ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
function proxyItemsPanel(panel, contextInfo) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.itemData = [];
|
||||||
|
|
||||||
|
var excludedUris = contextInfo.excludedUris;
|
||||||
|
var dataContainerElement = $("[name='proxyData']", panel).first();
|
||||||
|
var autoCompleteField = $("input[name='proxySelectorAC']", panel).first();
|
||||||
|
var searchStatusField = $("span[name='proxySelectorSearchStatus']", panel).first();
|
||||||
|
|
||||||
|
var parseTemplate = function(dataContainer) {
|
||||||
|
var templateDiv = $("div[name='template']", dataContainer)
|
||||||
|
var templateHtml = templateDiv.html();
|
||||||
|
templateDiv.remove();
|
||||||
|
return templateHtml;
|
||||||
|
};
|
||||||
|
var templateHtml = parseTemplate(dataContainerElement);
|
||||||
|
|
||||||
|
var displayItemData = function() {
|
||||||
|
$(".proxyInfoElement", dataContainerElement).remove();
|
||||||
|
|
||||||
|
for (i = 0; i < self.itemData.length; i++) {
|
||||||
|
self.itemData[i].element().appendTo(dataContainerElement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var getItemData = function() {
|
||||||
|
return self.itemData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* callback function */
|
||||||
|
var addItemData = function(selection) {
|
||||||
|
var imageUrl = contextInfo.defaultImageUrl;
|
||||||
|
if (selection.imageUrl) {
|
||||||
|
imageUrl = contextInfo.baseUrl + selection.imageUrl;
|
||||||
|
}
|
||||||
|
|
||||||
|
var info = new itemElement(templateHtml, selection.uri, selection.label, selection.classLabel,
|
||||||
|
imageUrl, removeItem);
|
||||||
|
self.itemData.unshift(info);
|
||||||
|
displayItemData();
|
||||||
|
}
|
||||||
|
|
||||||
|
var removeItem = function(info) {
|
||||||
|
var idx = self.itemData.indexOf(info);
|
||||||
|
if (idx != -1) {
|
||||||
|
self.itemData.splice(idx, 1);
|
||||||
|
}
|
||||||
|
displayItemData();
|
||||||
|
}
|
||||||
|
|
||||||
|
var parseOriginalData = function() {
|
||||||
|
var dataDivs = $("div[name='data']", dataContainerElement)
|
||||||
|
var data = [];
|
||||||
|
for (i = 0; i < dataDivs.length; i++) {
|
||||||
|
var dd = dataDivs[i];
|
||||||
|
var uri = $("p[name='uri']", dd).text();
|
||||||
|
var label = $("p[name='label']", dd).text();
|
||||||
|
var classLabel = $("p[name='classLabel']", dd).text();
|
||||||
|
var imageUrl = $("p[name='imageUrl']", dd).text();
|
||||||
|
data.push(new itemElement(templateHtml, uri, label, classLabel, imageUrl, removeItem));
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
this.itemData = parseOriginalData();
|
||||||
|
|
||||||
|
var setupAutoCompleteFields = function() {
|
||||||
|
var parms = {
|
||||||
|
query: contextInfo.query,
|
||||||
|
model: contextInfo.model,
|
||||||
|
url: contextInfo.sparqlQueryUrl
|
||||||
|
};
|
||||||
|
var updateStatus = new statusFieldUpdater(searchStatusField, 3).setText;
|
||||||
|
var autocompleteInfo = new proxyAutocomplete(parms, excludedUris, getItemData, addItemData, updateStatus)
|
||||||
|
autoCompleteField.autocomplete(autocompleteInfo);
|
||||||
|
}
|
||||||
|
setupAutoCompleteFields();
|
||||||
|
|
||||||
|
displayItemData();
|
||||||
|
}
|
||||||
|
|
||||||
|
function statusFieldUpdater(element, minLength) {
|
||||||
|
var emptyText = element.text();
|
||||||
|
var moreCharsText = element.attr('moreCharsText');
|
||||||
|
var noMatchText = element.attr('noMatchText');
|
||||||
|
|
||||||
|
this.setText = function(searchTermLength, numberOfResults) {
|
||||||
|
if (numberOfResults > 0) {
|
||||||
|
element.text('');
|
||||||
|
} else if (searchTermLength == 0) {
|
||||||
|
element.text(emptyText);
|
||||||
|
} else if (searchTermLength < minLength) {
|
||||||
|
element.text(moreCharsText);
|
||||||
|
} else {
|
||||||
|
element.text(noMatchText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var profileQuery = ""
|
||||||
|
+ "PREFIX fn: <http://www.w3.org/2005/xpath-functions#> \n"
|
||||||
|
+ "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#> \n"
|
||||||
|
+ "PREFIX foaf: <http://xmlns.com/foaf/0.1/> \n"
|
||||||
|
+ "PREFIX vitro: <http://vitro.mannlib.cornell.edu/ns/vitro/0.7#> \n"
|
||||||
|
+ "PREFIX vpublic: <http://vitro.mannlib.cornell.edu/ns/vitro/public#> \n"
|
||||||
|
+ "PREFIX auth: <http://vitro.mannlib.cornell.edu/ns/vitro/authorization#> \n"
|
||||||
|
+ "\n"
|
||||||
|
+ "SELECT DISTINCT ?uri ?label ?classLabel ?imageUrl \n"
|
||||||
|
+ "WHERE { \n"
|
||||||
|
+ " ?uri a foaf:Person ; \n"
|
||||||
|
+ " rdfs:label ?label ; \n"
|
||||||
|
+ " OPTIONAL { \n"
|
||||||
|
+ " ?uri vitro:mostSpecificType ?type. \n"
|
||||||
|
+ " ?type rdfs:label ?classLabel \n"
|
||||||
|
+ " } \n"
|
||||||
|
+ " OPTIONAL { \n"
|
||||||
|
+ " ?uri vpublic:mainImage ?imageUri. \n"
|
||||||
|
+ " ?imageUri vpublic:thumbnailImage ?thumbUri. \n"
|
||||||
|
+ " ?thumbUri vpublic:downloadLocation ?thumbstreamUri. \n"
|
||||||
|
+ " ?thumbstreamUri vpublic:directDownloadUrl ?imageUrl. \n"
|
||||||
|
+ " } \n"
|
||||||
|
+ " FILTER (REGEX(str(?label), '^%term%', 'i')) \n"
|
||||||
|
+ "} \n"
|
||||||
|
+ "ORDER BY ASC(?label) \n"
|
||||||
|
+ "LIMIT 25 \n";
|
||||||
|
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
var disableFormInUnsupportedBrowsers = function() {
|
||||||
|
var disableWrapper = $('#ie67DisableWrapper');
|
||||||
|
|
||||||
|
// Check for unsupported browsers only if the element exists on the page
|
||||||
|
if (disableWrapper.length) {
|
||||||
|
if (vitro.browserUtils.isIELessThan8()) {
|
||||||
|
disableWrapper.show();
|
||||||
|
$('.noIE67').hide();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (disableFormInUnsupportedBrowsers()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$("div[name='proxyProfilesPanel']").each(function(i) {
|
||||||
|
var context = {
|
||||||
|
excludedUris: [],
|
||||||
|
baseUrl: proxyContextInfo.baseUrl,
|
||||||
|
sparqlQueryUrl: proxyContextInfo.sparqlQueryUrl,
|
||||||
|
defaultImageUrl: proxyContextInfo.defaultImageUrl,
|
||||||
|
query: profileQuery,
|
||||||
|
model: ''
|
||||||
|
}
|
||||||
|
var ppp = new proxyItemsPanel(this, context);
|
||||||
|
this["ppp"]=ppp;
|
||||||
|
});
|
||||||
|
});
|
|
@ -168,7 +168,7 @@ function searchStatusField(element, minLength) {
|
||||||
|
|
||||||
this.setText = function(searchTermLength, numberOfResults) {
|
this.setText = function(searchTermLength, numberOfResults) {
|
||||||
if (numberOfResults > 0) {
|
if (numberOfResults > 0) {
|
||||||
element.text = '';
|
element.text('');
|
||||||
} else if (searchTermLength == 0) {
|
} else if (searchTermLength == 0) {
|
||||||
element.text(emptyText);
|
element.text(emptyText);
|
||||||
} else if (searchTermLength < minLength) {
|
} else if (searchTermLength < minLength) {
|
||||||
|
|
|
@ -60,4 +60,5 @@ var proxyMechanism = {
|
||||||
${scripts.add('<script type="text/javascript" src="${urls.base}/js/account/proxyUtils.js"></script>',
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/account/proxyUtils.js"></script>',
|
||||||
'<script type="text/javascript" src="${urls.base}/js/sparqlUtils.js"></script>',
|
'<script type="text/javascript" src="${urls.base}/js/sparqlUtils.js"></script>',
|
||||||
'<script type="text/javascript" src="${urls.base}/js/account/accountProxyCommon.js"></script>',
|
'<script type="text/javascript" src="${urls.base}/js/account/accountProxyCommon.js"></script>',
|
||||||
'<script type="text/javascript" src="${urls.base}/js/account/accountProxyProxiesPanel.js"></script>')}
|
'<script type="text/javascript" src="${urls.base}/js/account/accountProxyProxiesPanel.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')}
|
|
@ -0,0 +1,109 @@
|
||||||
|
<#-- $This file is distributed under the terms of the license in /doc/license.txt$ -->
|
||||||
|
|
||||||
|
<#-- Template for displaying list of user accounts -->
|
||||||
|
|
||||||
|
|
||||||
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/css/account/account.css" />')}
|
||||||
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/customForm.css" />')}
|
||||||
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/edit/forms/css/autocomplete.css" />')}
|
||||||
|
${stylesheets.add('<link rel="stylesheet" href="${urls.base}/js/jquery-ui/css/smoothness/jquery-ui-1.8.9.custom.css" />')}
|
||||||
|
|
||||||
|
<p>
|
||||||
|
<#if page.previous??>
|
||||||
|
<a href="${formUrls.list}?pageIndex='${page.previous}'">Previous</a>
|
||||||
|
</#if>
|
||||||
|
${page.current} of ${page.last}
|
||||||
|
<#if page.next??>
|
||||||
|
<a href="${formUrls.list}?pageIndex='${page.next}'">Next</a>
|
||||||
|
</#if>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<#list relationships as r>
|
||||||
|
<form action="${formUrls.edit} method="POST">
|
||||||
|
<table style="width: 100%;">
|
||||||
|
<tr>
|
||||||
|
<td style="border: thin solid black; width: 50%;">
|
||||||
|
<#assign p = r.proxyInfos[0]>
|
||||||
|
<table><tr>
|
||||||
|
<td>
|
||||||
|
<img class="photo-profile" width="90" src="${p.imageUrl}" alt="${p.label}">
|
||||||
|
</td>
|
||||||
|
<td class="proxyInfoElement">
|
||||||
|
${p.label}} |
|
||||||
|
<span class="class-label">${p.classLabel}</span>
|
||||||
|
<br>
|
||||||
|
<input type="hidden" value="${p.uri}" name="proxyUri">
|
||||||
|
</td>
|
||||||
|
</tr></table>
|
||||||
|
|
||||||
|
<input type="submit" name="deleteProxy" value="Delete this proxy" />
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td style="border: thin solid black">
|
||||||
|
<div id="edit-myProxy" name="proxyProfilesPanel">
|
||||||
|
<p>Add profile</p>
|
||||||
|
<p><input type="text" name="proxySelectorAC" class="acSelector" size="35" value="Select an existing last name"></p>
|
||||||
|
<p class="search-status">
|
||||||
|
<span name='proxySelectorSearchStatus'
|
||||||
|
moreCharsText='type more characters'
|
||||||
|
noMatchText='no match'> </span>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="selected-editors">Selected profiles:</p>
|
||||||
|
|
||||||
|
<#-- Magic div thst holds all of the proxy data and the template that shows how to display it. -->
|
||||||
|
<div name="proxyData">
|
||||||
|
<#list r.profileInfos as p>
|
||||||
|
<div name="data" style="display: none">
|
||||||
|
<p name="uri">${p.uri}</p>
|
||||||
|
<p name="label">${p.label}</p>
|
||||||
|
<p name="classLabel">${p.classLabel}</p>
|
||||||
|
<p name="imageUrl">${p.imageUrl}</p>
|
||||||
|
</div>
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
<#--
|
||||||
|
Each proxy will be shown using the HTML inside this element.
|
||||||
|
It must contain at least:
|
||||||
|
-- a link with templatePart="remove"
|
||||||
|
-- a hidden input field with templatePart="uriField"
|
||||||
|
-->
|
||||||
|
<div name="template" style="display: none">
|
||||||
|
<table>
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<img class="photo-profile" width="90" alt="%label%" src="%imageUrl%">
|
||||||
|
</td>
|
||||||
|
<td class="proxy-info">
|
||||||
|
%label% | <span class="class-label">%classLabel%</span>
|
||||||
|
<br />
|
||||||
|
<a class='remove-proxy' href="." templatePart="remove">Remove selection</a>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<input type="hidden" name="proxyUri" value="%uri%" >
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input type="submit" name="modifyProfileList" value="Save changes to profiles" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</form>
|
||||||
|
</#list>
|
||||||
|
|
||||||
|
<script type="text/javascript">
|
||||||
|
var proxyContextInfo = {
|
||||||
|
baseUrl: '${urls.base}',
|
||||||
|
sparqlQueryUrl: '${formUrls.sparqlQueryAjax}',
|
||||||
|
defaultImageUrl: '${formUrls.defaultImageUrl}',
|
||||||
|
matchingProperty: '${matchingProperty}',
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/jquery.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/jquery-ui/js/jquery-ui-1.8.9.custom.min.js"></script>')}
|
||||||
|
${scripts.add('<script type="text/javascript" src="${urls.base}/js/account/proxyUtils.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/sparqlUtils.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/account/accountProxyCommon.js"></script>',
|
||||||
|
'<script type="text/javascript" src="${urls.base}/js/account/accountProxyItemsPanel.js"></script>')}
|
|
@ -23,6 +23,10 @@
|
||||||
<li><a href="${siteConfig.userAccounts}">User accounts</a></li>
|
<li><a href="${siteConfig.userAccounts}">User accounts</a></li>
|
||||||
</#if>
|
</#if>
|
||||||
|
|
||||||
|
<#if siteConfig.manageProxies?has_content>
|
||||||
|
<li><a href="${siteConfig.manageProxies}">Manage Proxies</a></li>
|
||||||
|
</#if>
|
||||||
|
|
||||||
<#if siteConfig.startupStatus?has_content>
|
<#if siteConfig.startupStatus?has_content>
|
||||||
<li>
|
<li>
|
||||||
<a href="${siteConfig.startupStatus}">Startup Status</a>
|
<a href="${siteConfig.startupStatus}">Startup Status</a>
|
||||||
|
|
Loading…
Add table
Reference in a new issue