diff --git a/doc/install.html b/doc/install.html index 206382bd..be4a53c4 100644 --- a/doc/install.html +++ b/doc/install.html @@ -412,19 +412,36 @@ - Specify an SMTP host that the form will use for + Specify an SMTP host that the application will use for sending e-mail (Optional). If this is left blank, the contact form will - be hidden and disabled. + be hidden and disabled, and users will not be notified of changes to their accounts. - Vitro.smtpHost + email.smtpHost smtp.servername.edu + + + Specify an email address which will appear as the sender in e-mail + notifications to users (Optional). + If a user replies to the notification, this address will receive the reply. + If a user's e-mail address is invalid, this address will receive the error notice. + If this is left blank, users will not be notified of changes to their accounts. + + + + + email.replyTo + + + vivoAdmin@my.domain.edu + + Specify the JDBC URL of your database. Change @@ -564,18 +581,18 @@ - Specify the name of your first admin user for + Specify the email address of the root user account for the VIVO application. This user will have an initial temporary password - of 'defaultAdmin'. You will be prompted to create a new password on + of 'rootPassword'. You will be prompted to create a new password on first login. - initialAdminUser + rootUser.emailAddress - defaultAdmin + vivoAdmin@my.domain.edu @@ -711,9 +728,9 @@

If the startup was successful, you will see a welcome message informing you that you have successfully installed VIVO. Click the "Log - in" link near the upper right corner. Log in with the initialAdminUser - username you set up in Step IV. The initial password for the initialAdminUser - account is "defaultAdmin" (without the quotes). On first login, you + in" link near the upper right corner. Log in with the rootUser.emailAddress + you set up in Step IV. The initial password for the root + account is "rootPassword" (without the quotes). On first login, you will be prompted to select a new password and verify it a second time.

@@ -745,7 +762,7 @@ "Contact Us" form)

If you have configured your application to use the "Contact Us" - feature in Step IV (Vitro.smtpHost), you will also need to + feature in Step IV (email.smtpHost), you will also need to add an email address to the VIVO application.  This is the email to which the contact form will submit. It can be a list server or an individual's email address. @@ -758,7 +775,7 @@ Email Address" and submit the change.

- If you set the Vitro.smtpHost + If you set the email.smtpHost in Step IV and do NOT provide an email address in this step, your users will receive a java error in the interface. @@ -945,7 +962,9 @@ In addition, VIVO will try to associate the user with a profile page, so the user may edit his own profile data. VIVO will search the data model for a person with a property that matches the User’s network - ID. You need to tell VIVO what property should be used for matching. + ID + (the value of the property must be either a String literal or an untyped literal). + You need to tell VIVO what property should be used for matching. Insert a line like this in the deploy.properties file:

selfEditing.idMatchingProperty = [the URI of the property]
@@ -997,8 +1016,8 @@ -

upload.directory and LuceneSetup.indexDir are merged into vitro.home.directory.

+

upload.directory and LuceneSetup.indexDir are merged into vitro.home.directory [see JB for further details]

+ +

Email parameters in deploy.properties have changed. [see JB for further details]

+

Template changes [see RY for further details]

+ +

Changes to Authorization [see JB for further details]

+
diff --git a/productMods/templates/freemarker/body/individual/individual--foaf-organization.ftl b/productMods/templates/freemarker/body/individual/individual--foaf-organization.ftl index 15769149..56ee0069 100644 --- a/productMods/templates/freemarker/body/individual/individual--foaf-organization.ftl +++ b/productMods/templates/freemarker/body/individual/individual--foaf-organization.ftl @@ -5,7 +5,10 @@ <#-- Do not show the link for temporal visualization unless it's enabled --> <#if temporalVisualizationEnabled> <#assign classSpecificExtension> - <#include "individual-visualizationTemporalGraph.ftl"> +
+ <#include "individual-visualizationTemporalGraph.ftl"> + <#include "individual-visualizationMapOfScience.ftl"> +
diff --git a/productMods/templates/freemarker/body/individual/individual-menu.ftl b/productMods/templates/freemarker/body/individual/individual-menu.ftl new file mode 100644 index 00000000..3a08c665 --- /dev/null +++ b/productMods/templates/freemarker/body/individual/individual-menu.ftl @@ -0,0 +1,21 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Default VIVO individual profile page template (extends individual.ftl in vitro) --> + +<#include "individual-setup.ftl"> + +<#assign individualProductExtension> + <#-- Include for any class specific template additions --> + ${classSpecificExtension!} + + <#include "individual-overview.ftl"> + + + + +<#include "individual-menu-vitro.ftl"> + +${stylesheets.add('')} + +${headScripts.add('')} +${scripts.add('')} diff --git a/productMods/templates/freemarker/body/individual/individual.ftl b/productMods/templates/freemarker/body/individual/individual.ftl index 1ff67185..378da375 100644 --- a/productMods/templates/freemarker/body/individual/individual.ftl +++ b/productMods/templates/freemarker/body/individual/individual.ftl @@ -7,10 +7,11 @@ <#assign individualProductExtension> <#-- Include for any class specific template additions --> ${classSpecificExtension!} - + <#include "individual-overview.ftl"> + <#include "individual-vitro.ftl"> diff --git a/productMods/templates/freemarker/body/partials/individual/individual-menu-properties.ftl b/productMods/templates/freemarker/body/partials/individual/individual-menu-properties.ftl new file mode 100644 index 00000000..a6b9b6d2 --- /dev/null +++ b/productMods/templates/freemarker/body/partials/individual/individual-menu-properties.ftl @@ -0,0 +1,40 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Template for property listing on individual profile page --> + +<#import "lib-properties.ftl" as p> +<#list propertyGroups.all as group> + + <#assign groupName = group.getName(nameForOtherGroup)> +
+ + + <#-- Display the group heading --> + <#if groupName?has_content> +

${groupName?capitalize}

+ + + <#-- List the properties in the group --> + <#list group.properties as property> +
+ <#-- Property display name --> +

${property.name} <@p.addLink property editable /> <@p.verboseDisplay property />

+ <#-- List the statements for each property --> + +
+ +
+ \ No newline at end of file diff --git a/productMods/templates/freemarker/body/partials/individual/individual-menu-vitro.ftl b/productMods/templates/freemarker/body/partials/individual/individual-menu-vitro.ftl new file mode 100644 index 00000000..18f1a82b --- /dev/null +++ b/productMods/templates/freemarker/body/partials/individual/individual-menu-vitro.ftl @@ -0,0 +1,21 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Default individual profile page template --> +<#--@dumpAll /--> + +<#assign nameForOtherGroup = "other"> <#-- used by both individual-propertyGroupMenu.ftl and individual-properties.ftl --> + +<#-- Menu Ontology properties --> +<#include "individual-menu-properties.ftl"> + +${stylesheets.add('')} + +${headScripts.add('', + '', + '', + '', + '', + '', + '')} + +${scripts.add('')} diff --git a/productMods/templates/freemarker/body/partials/individual/individual-qrCodeFoafPerson.ftl b/productMods/templates/freemarker/body/partials/individual/individual-qrCodeFoafPerson.ftl index 467c52d4..7a0bc83c 100644 --- a/productMods/templates/freemarker/body/partials/individual/individual-qrCodeFoafPerson.ftl +++ b/productMods/templates/freemarker/body/partials/individual/individual-qrCodeFoafPerson.ftl @@ -3,5 +3,5 @@ <#include "individual-qrCodeGenerator.ftl"> <#if hasValidVCard()> -
  • qr icon
  • +
  • qr icon
  • \ No newline at end of file diff --git a/productMods/templates/freemarker/body/partials/individual/individual-qrCodeGenerator.ftl b/productMods/templates/freemarker/body/partials/individual/individual-qrCodeGenerator.ftl index 21e72246..094830b9 100644 --- a/productMods/templates/freemarker/body/partials/individual/individual-qrCodeGenerator.ftl +++ b/productMods/templates/freemarker/body/partials/individual/individual-qrCodeGenerator.ftl @@ -24,7 +24,7 @@ <#function getQrCodeUrlForVCard qrCodeWidth> - <#local qrData = individual.qrData > + <#local qrData = individual.doQrData() > <#local core = "http://vivoweb.org/ontology/core#"> <#local foaf = "http://xmlns.com/foaf/0.1/"> @@ -69,7 +69,7 @@ <#function getQrCodeUrlForLink qrCodeWidth> - <#local qrData = individual.qrData > + <#local qrData = individual.doQrData() > <#local url = qrData.externalUrl! > @@ -105,7 +105,7 @@ <#function hasValidVCard> - <#local qrData = individual.qrData > + <#local qrData = individual.doQrData() > <#local firstName = qrData.firstName! > <#local lastName = qrData.lastName! > diff --git a/productMods/templates/freemarker/body/partials/individual/individual-visualizationFoafPerson.ftl b/productMods/templates/freemarker/body/partials/individual/individual-visualizationFoafPerson.ftl index 586eaeb6..a2cdeebc 100644 --- a/productMods/templates/freemarker/body/partials/individual/individual-visualizationFoafPerson.ftl +++ b/productMods/templates/freemarker/body/partials/individual/individual-visualizationFoafPerson.ftl @@ -18,7 +18,10 @@
    <#if isAuthor> <#assign coAuthorIcon = "${urls.images}/visualization/co_author_icon.png"> + <#assign mapOfScienceIcon = "${urls.images}/visualization/mapofscience/vivo_scimap_icon_v001.png"> <#assign coAuthorVisUrl = individual.coAuthorVisUrl> + <#assign mapOfScienceVisUrl = individual.mapOfScienceUrl> + <#assign googleJSAPI = "https://www.google.com/jsapi?autoload=%7B%22modules%22%3A%5B%7B%22name%22%3A%22visualization%22%2C%22version%22%3A%221%22%2C%22packages%22%3A%5B%22imagesparkline%22%5D%7D%5D%7D"> information icon @@ -28,12 +31,21 @@ \ No newline at end of file diff --git a/productMods/templates/freemarker/body/partials/individual/propStatement-hasEditReviewRole.ftl b/productMods/templates/freemarker/body/partials/individual/propStatement-hasEditReviewRole.ftl new file mode 100644 index 00000000..a5cf8650 --- /dev/null +++ b/productMods/templates/freemarker/body/partials/individual/propStatement-hasEditReviewRole.ftl @@ -0,0 +1,34 @@ +<#-- $This file is distributed under the terms of the license in /doc/license.txt$ --> + +<#-- Custom object property statement view for core:hasEditorRole and core:hasReviewerRole. + + This template must be self-contained and not rely on other variables set for the individual page, because it + is also used to generate the property statement during a deletion. + --> + +<#import "lib-sequence.ftl" as s> +<#import "lib-datetime.ftl" as dt> + +<@showRole statement /> + +<#-- Use a macro to keep variable assignments local; otherwise the values carry over to the + next statement --> +<#macro showRole statement> + <#local linkedIndividual> + <#if statement.infoResource??> + ${statement.infoResourceLabel!statement.infoResourceName} + <#elseif statement.activity??> + ${statement.activityLabel!statement.activityName} + <#else> + ${statement.roleLabel!} + + + + <#local core = "http://vivoweb.org/ontology/core#"> + <#local dateTime> + <@dt.yearIntervalSpan "${statement.dateTimeStart!}" "${statement.dateTimeEnd!}" /> + + + ${linkedIndividual} ${statement.roleLabel!} ${dateTime!} + + \ No newline at end of file diff --git a/productMods/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl b/productMods/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl index a514fd3b..5baedc88 100644 --- a/productMods/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl +++ b/productMods/templates/freemarker/body/siteAdmin/siteAdmin-siteConfiguration.ftl @@ -18,13 +18,8 @@ - <#-- TODO This goes away when the UserAccounts are fully implemented - jblake --> - <#if siteConfig.urls.users??> -
  • User accounts
  • - - <#if siteConfig.urls.userList??> -
  • Manage user accounts (work in progress)
  • +
  • User accounts
  • diff --git a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl index ba803fc3..c146c671 100644 --- a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl +++ b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceSetup.ftl @@ -25,14 +25,62 @@ +<#assign mapOfScienceIcon = '${urls.images}/visualization/mapofscience/vivo_scimap_icon_v001.png'> + <#assign entityMapOfScienceDataURL = "${urls.base}${dataVisualizationURLRoot}?vis=${mapOfScienceVisParam}&uri=${entityURI}&output=json"> +<#assign entityMapOfScienceDisciplineCSVURL = "${urls.base}${dataVisualizationURLRoot}?vis=${mapOfScienceVisParam}&uri=${entityURI}&output=csv&vis_mode=discipline"> +<#assign entityMapOfScienceSubDisciplineCSVURL = "${urls.base}${dataVisualizationURLRoot}?vis=${mapOfScienceVisParam}&uri=${entityURI}&output=csv&vis_mode=subdiscipline"> +${scripts.add('', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '', + '')} + +<#-- CSS files --> + +${stylesheets.add('', + '', + '')} + diff --git a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl index 27a67ab7..c91cc66f 100644 --- a/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl +++ b/productMods/templates/freemarker/visualization/mapOfScience/mapOfScienceStandalone.ftl @@ -6,26 +6,79 @@ corresponding changes in the included Templates. --> <#include "mapOfScienceSetup.ftl"> -${scripts.add('', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '', - '')} +
    -<#-- CSS files --> +<#-- +
    +   + +
    +--> + +

    ${entityLabel}  +information icon

    -${stylesheets.add('', - '')} +
    Explore publications activity across 554 scientific sub-disciplines + information icon
    \ No newline at end of file +You can use VIVO's Map of Science visualization to see where ${entityLabel} is active in the world of science, based on publications that have been loaded into this VIVO instance. + +Overlaid circles are larger if ${entityLabel} has many publications in that sub-discipline, and are smaller if ${entityLabel} has fewer publications in that sub-discipline. + +Circles are overlaid on the Map of Science itself, which is made of 554 interconnected sub-disciplines, shown as grey dots here. A sub-discipline is defined as a cluster of journals. The Map of Science groups over 16,000 journals into 554 sub-disciplines using similarities in their lists of references and key terms. Sub-disciplines that are especially similar to one another are interconnected, and will be closer to one another on the map. + +For more information on this and other maps of science, see http://mapofscience.com or http://scimaps.org" /> +
    + +
    + + + +
    + 13 Disciplines | + 554 Sub-Disciplines + information icon +
    + +
    + +
    + +
    +
    +mapped % of publications + information icon
    + +
    + \ No newline at end of file diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/FileHarvestJob.java b/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/FileHarvestJob.java index 0f6a2b94..1a919097 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/FileHarvestJob.java +++ b/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/FileHarvestJob.java @@ -30,5 +30,11 @@ interface FileHarvestJob { * @param directory the directory containing files to harvest */ void performHarvest(File directory); + + /** + * The path to the file containing the RDF/XML triples that get added to VIVO. + * @return the path to the file containing the RDF/XML triples that get added to VIVO + */ + String getAdditionsFilePath(); } diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/TestFileController.java b/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/TestFileController.java index 800ab06a..f7b1c4f5 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/TestFileController.java +++ b/src/edu/cornell/mannlib/vitro/webapp/controller/harvester/TestFileController.java @@ -17,6 +17,8 @@ import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import javax.xml.parsers.DocumentBuilderFactory; + import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.servlet.ServletFileUpload; import org.apache.commons.logging.Log; @@ -24,6 +26,10 @@ import org.apache.commons.logging.LogFactory; import org.json.JSONException; import org.json.JSONObject; import org.skife.csv.SimpleReader; +import org.w3c.dom.Document; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import edu.cornell.mannlib.vitro.webapp.config.ConfigurationProperties; import edu.cornell.mannlib.vitro.webapp.controller.VitroRequest; @@ -284,8 +290,9 @@ public class TestFileController extends FreemarkerHttpServlet { //String path = getUploadPath(vreq); String script = job.getScript(); + String additionsFilePath = job.getAdditionsFilePath(); log.error("start harvest"); - runScript(getSessionId(request), script); + runScript(getSessionId(request), script, additionsFilePath); log.error("end harvest"); JSONObject json = new JSONObject(); @@ -330,9 +337,27 @@ public class TestFileController extends FreemarkerHttpServlet { boolean finished = !sessionIdToHarvestThread.containsKey(sessionId); + VitroRequest vreq = new VitroRequest(request); + ArrayList newlyAddedUrls = new ArrayList(); + if(finished) { + ArrayList newlyAddedUris = sessionIdToNewlyAddedUris.get(sessionId); + if(newlyAddedUris != null) { + for(String uri : newlyAddedUris) { + + String namespaceRoot = vreq.getWebappDaoFactory().getDefaultNamespace(); + + String suffix = uri.substring(namespaceRoot.length()); + String url = "display/" + suffix; + + newlyAddedUrls.add(uri); + } + } + } + JSONObject json = new JSONObject(); json.put("progressSinceLastCheck", progressSinceLastCheck); json.put("finished", finished); + json.put("newlyAddedUrls", newlyAddedUrls); response.getWriter().write(json.toString()); } @@ -359,11 +384,11 @@ public class TestFileController extends FreemarkerHttpServlet { } - private void runScript(String sessionId, String script) { + private void runScript(String sessionId, String script, String additionsFilePath) { if(!sessionIdToHarvestThread.containsKey(sessionId)) { - ScriptRunner runner = new ScriptRunner(sessionId, script); + ScriptRunner runner = new ScriptRunner(sessionId, script, additionsFilePath); sessionIdToHarvestThread.put(sessionId, runner); runner.start(); } @@ -409,7 +434,61 @@ public class TestFileController extends FreemarkerHttpServlet { return request.getSession().getId(); } + private ArrayList extractNewlyAddedUris(File additionsFile) { + ArrayList newlyAddedUris = new ArrayList(); + log.error(additionsFile.getAbsolutePath()); + + try { + Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(additionsFile); + NodeList descriptionNodes = document.getElementsByTagName("http://www.w3.org/1999/02/22-rdf-syntax-ns#Description"); + + int numNodes = descriptionNodes.getLength(); + for(int i = 0; i < numNodes; i++) { + Node node = descriptionNodes.item(i); + + ArrayList types = getRdfTypes(node); + if(types.contains("http://vivoweb.org/ontology/core#Grant")) { //todo: generalize + + NamedNodeMap attributes = node.getAttributes(); + Node aboutAttribute = attributes.getNamedItem("http://www.w3.org/1999/02/22-rdf-syntax-ns#about"); + if(aboutAttribute != null) { + String value = aboutAttribute.getNodeValue(); + newlyAddedUris.add(value); + } + } + } + + + + } catch(Exception e) { + log.error(e, e); + } + + return newlyAddedUris; + } + + private ArrayList getRdfTypes(Node descriptionNode) { + ArrayList rdfTypesList = new ArrayList(); + + NodeList children = descriptionNode.getChildNodes(); + int numChildren = children.getLength(); + for(int i = 0; i < numChildren; i++) { + Node child = children.item(i); + + String name = child.getNodeName(); + if(name.equals("http://www.w3.org/1999/02/22-rdf-syntax-ns#type")) { + NamedNodeMap attributes = child.getAttributes(); + Node resourceAttribute = attributes.getNamedItem("http://www.w3.org/1999/02/22-rdf-syntax-ns#resource"); + if(resourceAttribute != null) { + String value = resourceAttribute.getNodeValue(); + rdfTypesList.add(value); + } + } + } + + return rdfTypesList; + } @@ -435,18 +514,21 @@ public class TestFileController extends FreemarkerHttpServlet { super(cause); } } - - + + private Map sessionIdToHarvestThread = new Hashtable(); //Hashtable is threadsafe, HashMap is not private Map> sessionIdToUnsentLogLines = new Hashtable>(); //Hashtable is threadsafe, HashMap is not + private Map> sessionIdToNewlyAddedUris = new Hashtable>(); private class ScriptRunner extends Thread { private final String sessionId; private final String script; + private final String additionsFilePath; - public ScriptRunner(String sessionId, String script) { + public ScriptRunner(String sessionId, String script, String additionsFilePath) { this.sessionId = sessionId; this.script = script; + this.additionsFilePath = additionsFilePath; } @Override @@ -455,16 +537,16 @@ public class TestFileController extends FreemarkerHttpServlet { ArrayList unsentLogLines = sessionIdToUnsentLogLines.get(sessionId); if(unsentLogLines == null) { unsentLogLines = new ArrayList(); - sessionIdToUnsentLogLines.put(sessionId, unsentLogLines); + sessionIdToUnsentLogLines.put(this.sessionId, unsentLogLines); } - File scriptFile = createScriptFile(script); + File scriptFile = createScriptFile(this.script); String command = "/bin/bash " + getHarvesterPath() + "scripts/temp/" + scriptFile.getName(); log.info("Running command: " + command); Process pr = Runtime.getRuntime().exec(command); - + //try { Thread.sleep(15000); } catch(InterruptedException e) {log.error(e, e);} BufferedReader processOutputReader = new BufferedReader(new InputStreamReader(pr.getInputStream())); @@ -481,13 +563,19 @@ public class TestFileController extends FreemarkerHttpServlet { } int exitVal; - + try { exitVal = pr.waitFor(); } catch(InterruptedException e) { throw new IOException(e.getMessage(), e); } + + File additionsFile = new File(this.additionsFilePath); + ArrayList newlyAddedUris = extractNewlyAddedUris(additionsFile); + log.error("newly added URIs size: " + newlyAddedUris.size()); + sessionIdToNewlyAddedUris.put(this.sessionId, newlyAddedUris); + log.debug("Harvester script exited with error code " + exitVal); log.info("Harvester script execution complete"); } catch (IOException e) { @@ -498,9 +586,7 @@ public class TestFileController extends FreemarkerHttpServlet { } } } - } - } @@ -542,6 +628,7 @@ class CsvHarvestJob implements FileHarvestJob { public CsvHarvestJob(VitroRequest vreq, String templateFileName, String namespace) { this.vreq = vreq; this.templateFile = new File(getTemplateFileDirectory() + templateFileName); + log.error(getTemplateFileDirectory() + templateFileName); this.namespace = namespace; } @@ -607,13 +694,24 @@ class CsvHarvestJob implements FileHarvestJob { * @return an error message if the two lines don't match, or null if they do */ private String validateCsvFirstLine(String[] templateFirstLine, String[] line) { - String errorMessage = "File header does not match specification"; - if(line.length != templateFirstLine.length) - return errorMessage; + String errorMessage = "File header does not match template"; + if(line.length != templateFirstLine.length) { + //return errorMessage + ": " + "file header columns = " + line.length + ", template columns = " + templateFirstLine.length; + String errorMsg = ""; + errorMsg += "file header items: "; + for(int i = 0; i < line.length; i++) { + errorMsg += line[i] + ", "; + } + errorMsg += "template items: "; + for(int i = 0; i < templateFirstLine.length; i++) { + errorMsg += templateFirstLine[i] + ", "; + } + return errorMsg; + } for(int i = 0; i < line.length; i++) { if(!line[i].equals(templateFirstLine[i])) - return errorMessage; + return errorMessage + ": file header column " + (i + 1) + " = " + line[i] + ", template column " + (i + 1) + " = " + templateFirstLine[i]; } return null; } @@ -675,6 +773,12 @@ class CsvHarvestJob implements FileHarvestJob { public void performHarvest(File directory) { } + + @Override + public String getAdditionsFilePath() { + + return TestFileController.getHarvesterPath() + "harvested-data/csv/additions.rdf.xml"; + } diff --git a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java index a4b9182d..d7584ec1 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java +++ b/src/edu/cornell/mannlib/vitro/webapp/controller/visualization/VisualizationFrameworkConstants.java @@ -87,6 +87,14 @@ public class VisualizationFrameworkConstants { public static final String COPI_NETWORK_STREAM_VIS_MODE = "copi_network_stream"; public static final String COPI_NETWORK_DOWNLOAD_VIS_MODE = "copi_network_download"; + + /* + * Vis modes for Map of Science Handler + * */ + public static final String DISCIPLINE_TO_ACTIVTY_VIS_MODE = "discipline"; + public static final String SUBDISCIPLINE_TO_ACTIVTY_VIS_MODE = "subdiscipline"; + + /* * These values represent possible utilities vis modes. * */ @@ -117,6 +125,7 @@ public class VisualizationFrameworkConstants { public static final String UTILITIES_VIS = "utilities"; public static final String ENTITY_COMPARISON_VIS = "entity_comparison"; public static final String PUBLICATION_TEMPORAL_VIS_SHORT_URL = "publication-graph"; + public static final String MAP_OF_SCIENCE_VIS_SHORT_URL = "map-of-science"; public static final String GRANT_TEMPORAL_VIS_SHORT_URL = "grant-graph"; public static final String CO_PI_VIS = "coprincipalinvestigator"; diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/OrganizationUtilityFunctions.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/OrganizationUtilityFunctions.java index ddc92f4b..72b68411 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/OrganizationUtilityFunctions.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/entitycomparison/OrganizationUtilityFunctions.java @@ -92,7 +92,7 @@ public class OrganizationUtilityFunctions { QueryRunner highestLevelOrganizationQueryHandler = new GenericQueryRunner( fieldLabelToOutputFieldLabel, aggregationRules, whereClause, - groupOrderClause, dataset, log); + groupOrderClause, dataset); String highestLevelOrgURI = OrganizationUtilityFunctions .getHighestLevelOrganizationURI( diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/mapofscience/MapOfScienceVisualizationRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/mapofscience/MapOfScienceVisualizationRequestHandler.java index b3f94f8e..2e68c671 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/mapofscience/MapOfScienceVisualizationRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/mapofscience/MapOfScienceVisualizationRequestHandler.java @@ -14,9 +14,7 @@ import mapping.ScienceMappingResult; import org.apache.commons.lang.StringEscapeUtils; import org.apache.commons.lang.StringUtils; -import org.apache.commons.lang.math.NumberUtils; import org.apache.commons.logging.Log; -import org.jgrapht.util.MathUtil; import com.google.gson.Gson; import com.hp.hpl.jena.query.Dataset; @@ -89,11 +87,48 @@ public class MapOfScienceVisualizationRequestHandler implements // return prepareStandaloneMarkupResponse(vitroRequest, entityURI); } + + + private Map getSubjectPersonEntityAndGenerateDataResponse( + VitroRequest vitroRequest, Log log, Dataset dataset, + String subjectEntityURI, VisConstants.DataVisMode dataOuputFormat) + throws MalformedQueryParametersException { + + Map documentURIForAssociatedPeopleTOVO = new HashMap(); + + + Entity personEntity = SelectOnModelUtilities + .getSubjectPersonEntity(dataset, subjectEntityURI); + + if (personEntity.getSubEntities() != null) { + + documentURIForAssociatedPeopleTOVO = SelectOnModelUtilities + .getPublicationsWithJournalForAssociatedPeople(dataset, personEntity.getSubEntities()); + + } + + if (documentURIForAssociatedPeopleTOVO.isEmpty()) { + + if (VisConstants.DataVisMode.JSON.equals(dataOuputFormat)) { + return prepareStandaloneDataErrorResponse(); + } else { + return prepareDataErrorResponse(); + } + + } else { + + if (VisConstants.DataVisMode.JSON.equals(dataOuputFormat)) { + return prepareStandaloneDataResponse(vitroRequest, personEntity); + } else { + return prepareDataResponse(vitroRequest, personEntity); + } + } + } private Map getSubjectEntityAndGenerateDataResponse( VitroRequest vitroRequest, Log log, Dataset dataset, String subjectEntityURI, VisConstants.DataVisMode dataOuputFormat) - throws MalformedQueryParametersException { + throws MalformedQueryParametersException { Entity organizationEntity = SelectOnModelUtilities .getSubjectOrganizationHierarchy(dataset, subjectEntityURI); @@ -123,7 +158,23 @@ public class MapOfScienceVisualizationRequestHandler implements organizationEntity = OrganizationUtilityFunctions.mergeEntityIfShareSameURI( organizationEntity, organizationWithAssociatedPeople); - } + } /*else { + + + // This is for just people. + Set test = new HashSet(); + + test.add(new SubEntity(subjectEntityURI)); + + documentURIForAssociatedPeopleTOVO = SelectOnModelUtilities + .getPublicationsWithJournalForAssociatedPeople(dataset, test); + + organizationEntity = OrganizationUtilityFunctions.mergeEntityIfShareSameURI( + organizationEntity, + organizationWithAssociatedPeople); + + + }*/ if (allDocumentURIToVOs.isEmpty() && documentURIForAssociatedPeopleTOVO.isEmpty()) { @@ -163,18 +214,34 @@ public class MapOfScienceVisualizationRequestHandler implements entityLabel = "no-organization"; } - String outputFileName = UtilityFunctions.slugify(entityLabel) - + "_discipline-to-publications" + ".csv"; - + String outputFileName = UtilityFunctions.slugify(entityLabel); Map fileData = new HashMap(); - fileData.put(DataVisualizationController.FILE_NAME_KEY, - outputFileName); fileData.put(DataVisualizationController.FILE_CONTENT_TYPE_KEY, "application/octet-stream"); - fileData.put(DataVisualizationController.FILE_CONTENT_KEY, - getDisciplineToPublicationsCSVContent(entity)); + + if (VisualizationFrameworkConstants.SUBDISCIPLINE_TO_ACTIVTY_VIS_MODE + .equalsIgnoreCase(vitroRequest.getParameter(VisualizationFrameworkConstants.VIS_MODE_KEY))) { + + fileData.put(DataVisualizationController.FILE_CONTENT_KEY, + getSubDisciplineToPublicationsCSVContent(entity)); + + outputFileName += "_subdiscipline-to-publications" + ".csv"; + + } else { + + fileData.put(DataVisualizationController.FILE_CONTENT_KEY, + getDisciplineToPublicationsCSVContent(entity)); + + outputFileName += "_discipline-to-publications" + ".csv"; + + } + + fileData.put(DataVisualizationController.FILE_NAME_KEY, + outputFileName); + + return fileData; } @@ -227,14 +294,26 @@ public class MapOfScienceVisualizationRequestHandler implements currentDataVisMode = VisConstants.DataVisMode.JSON; } + if (UtilityFunctions.isEntityAPerson(vitroRequest, entityURI)) { + + return getSubjectPersonEntityAndGenerateDataResponse( + vitroRequest, + log, + dataset, + entityURI, + currentDataVisMode); + + } else { - return getSubjectEntityAndGenerateDataResponse( - vitroRequest, - log, - dataset, - entityURI, - currentDataVisMode); + return getSubjectEntityAndGenerateDataResponse( + vitroRequest, + log, + dataset, + entityURI, + currentDataVisMode); + } + } @@ -274,7 +353,6 @@ public class MapOfScienceVisualizationRequestHandler implements body.put("entityLabel", organizationLabel); body.put("vivoDefaultNamespace", vreq.getWebappDaoFactory().getDefaultNamespace()); - return new TemplateResponseValues(standaloneTemplate, body); } @@ -412,17 +490,7 @@ public class MapOfScienceVisualizationRequestHandler implements csvFileContent.append("Discipline, Publication Count, % Activity\n"); - Set publicationsForEntity = new HashSet(); - - for (SubEntity subEntity : subjectEntity.getSubEntities()) { - - publicationsForEntity.addAll(subEntity.getActivities()); - } - - - PublicationJournalStats publicationStats = getPublicationJournalStats(publicationsForEntity); - - ScienceMappingResult result = getScienceMappingResult(publicationStats.journalToPublicationCount); + ScienceMappingResult result = extractScienceMappingResultFromActivities(subjectEntity); Map disciplineToPublicationCount = new HashMap(); @@ -469,6 +537,59 @@ public class MapOfScienceVisualizationRequestHandler implements return csvFileContent.toString(); } + + private String getSubDisciplineToPublicationsCSVContent(Entity subjectEntity) { + + StringBuilder csvFileContent = new StringBuilder(); + + csvFileContent.append("Sub-Discipline, Publication Count, % Activity\n"); + + ScienceMappingResult result = extractScienceMappingResultFromActivities(subjectEntity); + + Float totalMappedPublications = new Float(0); + + if (result != null) { + + DecimalFormat percentageActivityFormat = new DecimalFormat("#.#"); + + totalMappedPublications = result.getMappedPublications(); + + for (Map.Entry currentMappedSubdiscipline : result.getMappedResult().entrySet()) { + + csvFileContent.append(StringEscapeUtils.escapeCsv(MapOfScienceConstants.SUB_DISCIPLINE_ID_TO_LABEL + .get(currentMappedSubdiscipline.getKey()))); + csvFileContent.append(", "); + csvFileContent.append(percentageActivityFormat.format(currentMappedSubdiscipline.getValue())); + csvFileContent.append(", "); + + if (totalMappedPublications > 0) { + csvFileContent.append(percentageActivityFormat.format(100 * currentMappedSubdiscipline.getValue() / totalMappedPublications)); + } else { + csvFileContent.append("Not Available"); + } + csvFileContent.append("\n"); + } + } + + return csvFileContent.toString(); + } + + private ScienceMappingResult extractScienceMappingResultFromActivities( + Entity subjectEntity) { + Set publicationsForEntity = new HashSet(); + + for (SubEntity subEntity : subjectEntity.getSubEntities()) { + + publicationsForEntity.addAll(subEntity.getActivities()); + } + + + PublicationJournalStats publicationStats = getPublicationJournalStats(publicationsForEntity); + + ScienceMappingResult result = getScienceMappingResult(publicationStats.journalToPublicationCount); + return result; + } + private class PublicationJournalStats { int noJournalCount; diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/OrganizationAssociatedPeopleModelWithTypesConstructor.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/OrganizationAssociatedPeopleModelWithTypesConstructor.java index 3d55858f..693ecd86 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/OrganizationAssociatedPeopleModelWithTypesConstructor.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/OrganizationAssociatedPeopleModelWithTypesConstructor.java @@ -64,7 +64,7 @@ public class OrganizationAssociatedPeopleModelWithTypesConstructor implements Mo private Model executeQuery(String constructQuery) { - System.out.println("in constructed model for associated people for organization"); + log.debug("in constructed model for associated people for organization"); Model constructedModel = ModelFactory.createDefaultModel(); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PeopleToPublicationsModelConstructor.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PeopleToPublicationsModelConstructor.java index d716054d..36f3fe77 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PeopleToPublicationsModelConstructor.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PeopleToPublicationsModelConstructor.java @@ -67,7 +67,7 @@ public class PeopleToPublicationsModelConstructor implements ModelConstructor { private Model executeQuery(String constructQuery) { - System.out.println("in constructed model for ALL people publications "); + log.debug("in constructed model for ALL people publications "); Model constructedModel = ModelFactory.createDefaultModel(); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PersonToPublicationsModelConstructor.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PersonToPublicationsModelConstructor.java index fcfbbd29..34571bae 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PersonToPublicationsModelConstructor.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/modelconstructor/PersonToPublicationsModelConstructor.java @@ -70,7 +70,7 @@ public class PersonToPublicationsModelConstructor implements ModelConstructor { private Model executeQuery(String constructQuery) { - System.out.println("in constructed model for person to publications " + personURI); + log.debug("in constructed model for person to publications " + personURI); Model constructedModel = ModelFactory.createDefaultModel(); diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/utilities/UtilitiesRequestHandler.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/utilities/UtilitiesRequestHandler.java index 95572651..750a30ec 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/utilities/UtilitiesRequestHandler.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/utilities/UtilitiesRequestHandler.java @@ -106,7 +106,7 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler { "", whereClause, "", - dataset, log); + dataset); return getThumbnailInformation(imageQueryHandler.getQueryResult(), fieldLabelToOutputFieldLabel, vitroRequest); @@ -131,7 +131,7 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler { aggregationRules, whereClause, groupOrderClause, - dataset, log); + dataset); Gson publicationsInformation = new Gson(); @@ -162,7 +162,7 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler { aggregationRules, whereClause, "", - dataset, log); + dataset); Gson grantsInformation = new Gson(); @@ -309,7 +309,7 @@ public class UtilitiesRequestHandler implements VisualizationRequestHandler { aggregationRules, whereClause, groupOrderClause, - dataset, log); + dataset); return getHighestLevelOrganizationTemporalGraphVisURL( highestLevelOrganizationQueryHandler.getQueryResult(), diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/GenericQueryRunner.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/GenericQueryRunner.java index 25ac9a57..11fa1e13 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/GenericQueryRunner.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/GenericQueryRunner.java @@ -4,7 +4,6 @@ package edu.cornell.mannlib.vitro.webapp.visualization.visutils; import java.util.Map; -import org.apache.commons.logging.Log; import com.hp.hpl.jena.query.Dataset; import com.hp.hpl.jena.query.Query; @@ -42,7 +41,7 @@ public class GenericQueryRunner implements QueryRunner { String aggregationRules, String whereClause, String groupOrderClause, - Dataset dataset, Log log) { + Dataset dataset) { this.fieldLabelToOutputFieldLabel = fieldLabelToOutputFieldLabel; this.aggregationRules = aggregationRules; diff --git a/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/SelectOnModelUtilities.java b/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/SelectOnModelUtilities.java index cbc6e297..a3c3b049 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/SelectOnModelUtilities.java +++ b/src/edu/cornell/mannlib/vitro/webapp/visualization/visutils/SelectOnModelUtilities.java @@ -72,6 +72,53 @@ public class SelectOnModelUtilities { return entityWithSubOrganizations; } + public static Entity getSubjectPersonEntity(Dataset dataset, + String subjectEntityURI) throws MalformedQueryParametersException { + + Map fieldLabelToOutputFieldLabel = new HashMap(); + fieldLabelToOutputFieldLabel.put("authorLabel", QueryFieldLabels.AUTHOR_LABEL); + + String whereClause = "" + + " <" + subjectEntityURI + "> rdfs:label ?authorLabel . "; + + QueryRunner personQuery = + new GenericQueryRunner(fieldLabelToOutputFieldLabel, + "", + whereClause, + "", + dataset); + + Entity personEntity = new Entity(subjectEntityURI); + + ResultSet queryResult = personQuery.getQueryResult(); + + while (queryResult.hasNext()) { + + QuerySolution solution = queryResult.nextSolution(); + + RDFNode personLabelNode = solution.get(QueryFieldLabels.AUTHOR_LABEL); + if (personLabelNode != null) { + personEntity.setEntityLabel(personLabelNode.toString()); + } + + } + + /* + * We are adding A person as it's own subentity in order to make our code for geenrating csv, json + * & other data as streamlined as possible between entities of type Organization & Person. + * */ + SubEntity subEntity = new SubEntity(subjectEntityURI, personEntity.getEntityLabel()); + subEntity.setEntityClass(VOConstants.EntityClassType.PERSON); + + personEntity.addSubEntity(subEntity); + +// Entity entityWithParentOrganizations = getAllParentOrganizations(dataset, subjectEntityURI); +// +// personEntity.addParents(entityWithParentOrganizations.getParents()); + + return personEntity; + } + public static Entity getAllParentOrganizations(Dataset dataset, String subjectEntityURI) throws MalformedQueryParametersException { Model organizationModel = ModelConstructorUtilities diff --git a/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java b/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java index 4b02eb18..3cc9efad 100644 --- a/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java +++ b/src/edu/cornell/mannlib/vitro/webapp/web/templatemodels/individual/IndividualTemplateModel.java @@ -86,6 +86,13 @@ public class IndividualTemplateModel extends BaseIndividualTemplateModel { return getVisUrl(temporalVisURL); } + public String getMapOfScienceUrl() { + + String mapOfScienceVisURL = getBaseVisUrl() + "/" + VisualizationFrameworkConstants.MAP_OF_SCIENCE_VIS_SHORT_URL + "/"; + + return getVisUrl(mapOfScienceVisURL); + } + public String getSelfEditingId() { String id = null; String idMatchingProperty = ConfigurationProperties.getBean(getServletContext()).getProperty("selfEditing.idMatchingProperty"); @@ -102,7 +109,7 @@ public class IndividualTemplateModel extends BaseIndividualTemplateModel { return id; } - public Map getQrData() { + public Map doQrData() { if(qrData == null) qrData = generateQrData(); return qrData; @@ -120,15 +127,15 @@ public class IndividualTemplateModel extends BaseIndividualTemplateModel { Collection phoneNumbers = wdf.getDataPropertyStatementDao().getDataPropertyStatementsForIndividualByDataPropertyURI(individual, core + "phoneNumber"); Collection emails = wdf.getDataPropertyStatementDao().getDataPropertyStatementsForIndividualByDataPropertyURI(individual, core + "email"); - if(firstNames.size() > 0) + if(firstNames != null && ! firstNames.isEmpty()) qrData.put("firstName", firstNames.toArray(new DataPropertyStatement[firstNames.size()])[0].getData()); - if(lastNames.size() > 0) + if(lastNames != null && ! lastNames.isEmpty()) qrData.put("lastName", lastNames.toArray(new DataPropertyStatement[firstNames.size()])[0].getData()); - if(preferredTitles.size() > 0) + if(preferredTitles != null && ! preferredTitles.isEmpty()) qrData.put("preferredTitle", preferredTitles.toArray(new DataPropertyStatement[firstNames.size()])[0].getData()); - if(phoneNumbers.size() > 0) + if(phoneNumbers != null && ! phoneNumbers.isEmpty()) qrData.put("phoneNumber", phoneNumbers.toArray(new DataPropertyStatement[firstNames.size()])[0].getData()); - if(emails.size() > 0) + if(emails != null && ! emails.isEmpty()) qrData.put("email", emails.toArray(new DataPropertyStatement[firstNames.size()])[0].getData()); String tempUrl = vreq.getRequestURL().toString(); diff --git a/themes/wilma/css/wilma.css b/themes/wilma/css/wilma.css index f50b1de8..c9a04e6a 100644 --- a/themes/wilma/css/wilma.css +++ b/themes/wilma/css/wilma.css @@ -78,7 +78,8 @@ h5 { /* -------------------------------------------------> */ /* EDITING STYLES ----------------------------------> */ /* -------------------------------------------------> */ -input[type="text"], +input[type="text"], +select, input[type="password"] { border: 0; font-size: 14px; @@ -410,8 +411,8 @@ ul#header-nav { ul#header-nav li { float: left; display: block; - padding-left: 10px; - padding-right: 10px; + padding-left: 20px; + padding-right: 20px; border-right: 1px solid #7c7d7f; font-size: .7em; color: #fff; @@ -420,6 +421,7 @@ ul#header-nav li.last { border-right: none; } ul#header-nav li:last-child { + padding-left: 10px; padding-right: 0; border-right: none; } @@ -559,7 +561,7 @@ body.login #login { border-bottom: none; } #error-alert { - margin: 0 12px; + margin-left: 0; margin-bottom: 12px; padding: 12px; padding-bottom: 12px; @@ -1287,6 +1289,12 @@ a.all-vivo-publications { font-size: .8em !important; text-decoration: underline; } +/* <------ MAP O' SCIENCE */ +#map-of-science h3 a { + color: #2485AE; + font-size: .8em !important; + text-decoration: underline; +} /* COAUTHORS ------> */ img.co-author { border: 2px solid #ebebeb; @@ -1459,12 +1467,14 @@ h2#hasResearchArea .verbosePropertyListing { display: block; } /* -------------------------------------------------> */ -/* ACCOUNTS ----------------------------------------> */ +/* ACCOUNTS PAGE -----------------------------------> */ /* -------------------------------------------------> */ .account-feedback p { - padding: 10px; - background-color: #F0F0F0; line-height: 1.5em; + border: 1px dotted #E2C822; + background-color: #FFF9D7; + padding: .5em; + margin-bottom: 20px; } table#account { table-layout: auto; @@ -1479,14 +1489,20 @@ table#account { table#account caption { display: none; } -table#account thead { +table#account th{ + background-color: #fff; } table#account td { vertical-align: top; padding: .5em; - background-color: rgba(200, 200, 180,.25); border: 1px solid #F7F9F9; font-size: .9em; +} +table#account tr { + background-color: #fff; +} +table#account tr:nth-child(2n+1) { + background-color: rgba(200, 200, 180,.25); } #filter-roles { float: left; @@ -1494,19 +1510,20 @@ table#account td { } #search-accounts { float: right; + height: 60px; } .accounts { clear: left; overflow: hidden; - border-top: 1px solid #c1bfbf; + border-top: 1px dotted #e1e5e7; padding-top: 0; - border-bottom: 1px solid #c1bfbf; + border-bottom: 1px dotted #e1e5e7; padding-bottom: 0; width: 100%; } -.delete-account { +section.accounts .delete-account{ float: left; - border: 2px solid red; + margin-top: 13px; } .display-tools { float: left; @@ -1517,4 +1534,111 @@ table#account td { } .accounts-per-page-form { display: inline-block; +} +/* -------------------------------------------------> */ +/* ADD ACCOUNTS -----------------------------------> */ +/* -------------------------------------------------> */ +#add-account p { + margin-top: 15px; +} +#reset-password { + background-color: green; +} +form.customForm #reset-password { + margin-top: 20px; +} +#add-account .note { + padding-bottom: 20px; + padding-top: 0; + margin-top: 5px; +} +/* -------------------------------------------------> */ +/* DROP DOWN USER MENU ----------------------------> */ +/* -------------------------------------------------> */ + +/* LEVEL ONE */ +ul.dropdown { + position: relative; +} +ul.dropdown li { + float: left; + zoom: 1; + padding: 0 !important; +} +ul.dropdown li a { + display: block; + font-size: 1.4em; +} +ul.dropdown li#user-menu { + background: url(../images/arrow-down-over-account.gif) right 9px no-repeat; + min-width:110px; +} +ul.dropdown li#user-menu a { + margin-right: 28px; + margin-left:10px; +} +ul.dropdown li#user-menu.hover, +ul.dropdown li#user-menu:hover { + color: #000 !important; + position: relative; + background: #fff url(../images/arrow-down-account.gif) right 9px no-repeat; + padding-right: 10px; + border-bottom: 1px solid #cdcfcf; +} +ul.dropdown li.hover a, +ul.dropdown li:hover a { + color: #000 !important; + margin-left:10px; +} +/* LEVEL TWO */ +ul.dropdown ul.sub_menu { + background-color: #fff; + font-size: 1.4em; + visibility: hidden; + position: absolute; + top: 100%; + right: 0; + z-index: 999; + color: #000; +} +ul.dropdown ul.sub_menu li { + float: none; + clear: both; + padding-left: 14px !important; + width: 96px; + border-right: none !important; + border-bottom: 1px solid #cdcfcf; + background: #fff url(../images/arrow-menu-account.gif) 7px 8px no-repeat; +} +ul.dropdown ul.sub_menu li:last-child { + width: 96px; + +} +/* IE 6 & 7 Needs Inline Block */ +/* ADD IN IE6.css and IE7.css*/ +ul.dropdown ul.sub_menu li a { + width: 90%; + display: inline-block; + color: #000 !important; + background-color: #fff; + padding: 0; + padding-left: 0px; + height: 24px; +} +ul.dropdown ul.sub_menu li.inactive { + color: #aab0ae !important; + font-size: 1em !important; + padding-left: 22px !important; + width: 88px; +} +ul.dropdown ul.sub_menu li a:hover, +ul.dropdown ul.sub_menu li a.hover { + color: #999 !important; +} +/* LEVEL THREE */ +ul.dropdown ul ul { + left: 100%; top: 0; +} +ul.dropdown li:hover > ul { + visibility: visible; } \ No newline at end of file diff --git a/themes/wilma/images/arrow-down-account.gif b/themes/wilma/images/arrow-down-account.gif new file mode 100644 index 00000000..0f5463eb Binary files /dev/null and b/themes/wilma/images/arrow-down-account.gif differ diff --git a/themes/wilma/images/arrow-down-over-account.gif b/themes/wilma/images/arrow-down-over-account.gif new file mode 100644 index 00000000..4db412c9 Binary files /dev/null and b/themes/wilma/images/arrow-down-over-account.gif differ diff --git a/themes/wilma/images/arrow-menu-account.gif b/themes/wilma/images/arrow-menu-account.gif new file mode 100644 index 00000000..f37a72ec Binary files /dev/null and b/themes/wilma/images/arrow-menu-account.gif differ diff --git a/themes/wilma/templates/identity.ftl b/themes/wilma/templates/identity.ftl index fea0791f..8b2dbbd1 100644 --- a/themes/wilma/templates/identity.ftl +++ b/themes/wilma/templates/identity.ftl @@ -9,17 +9,30 @@