From ac92a83bc170805bd02f703a9645e53652ed82ea Mon Sep 17 00:00:00 2001 From: "Mark M. Florida" <markflorida@wustl.edu> Date: Mon, 17 Oct 2016 22:18:47 -0500 Subject: [PATCH] XNAT-4533, more: Added Plugin Settings page - 'Administer > Plugin Settings' menu option will show when there's an installed plugin that has site-wide settings. The mechanism for this is clunky and could be improved if there was a way for plugins to register themselves as having site-wide settings. Split up items in 'Administer' menu for more granularity in inserting menu items. Other refactoring to support these features, including a new panel.form contentType option 'text/json' that submits JSON as text (needed for XSync plugin). (WHY!?) --- .../webapp/page/admin/plugins/content.jsp | 103 ++++++++++++++++++ src/main/webapp/page/admin/plugins/index.jsp | 20 ++++ src/main/webapp/page/content.jsp | 12 +- src/main/webapp/scripts/globals.js | 10 +- .../scripts/xnat/admin/pluginSettings.js | 89 +++++++++++++++ src/main/webapp/scripts/xnat/spawner.js | 2 - src/main/webapp/scripts/xnat/ui/panel.js | 7 +- src/main/webapp/scripts/xnat/ui/select.js | 41 ++++--- src/main/webapp/scripts/xnat/ui/tabs.js | 19 ++-- src/main/webapp/scripts/xnat/xhr.js | 10 +- .../screens/topBar/Administer/Automation.vm | 3 + .../screens/topBar/Administer/DataTypes.vm | 3 + .../screens/topBar/Administer/Default.vm | 90 +++++++++++++-- .../screens/topBar/Administer/Email.vm | 3 + .../screens/topBar/Administer/Groups.vm | 3 + .../screens/topBar/Administer/More.vm | 3 + .../screens/topBar/Administer/Pipelines.vm | 3 + .../topBar/Administer/PluginSettings.vm | 5 + .../screens/topBar/Administer/SiteAdmin.vm | 3 + .../screens/topBar/Administer/Users.vm | 3 + 20 files changed, 389 insertions(+), 43 deletions(-) create mode 100755 src/main/webapp/page/admin/plugins/content.jsp create mode 100644 src/main/webapp/page/admin/plugins/index.jsp create mode 100644 src/main/webapp/scripts/xnat/admin/pluginSettings.js create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/Automation.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/DataTypes.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/Email.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/Groups.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/More.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/Pipelines.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/PluginSettings.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/SiteAdmin.vm create mode 100644 src/main/webapp/xnat-templates/screens/topBar/Administer/Users.vm diff --git a/src/main/webapp/page/admin/plugins/content.jsp b/src/main/webapp/page/admin/plugins/content.jsp new file mode 100755 index 00000000..c9e1fac5 --- /dev/null +++ b/src/main/webapp/page/admin/plugins/content.jsp @@ -0,0 +1,103 @@ +<%@ page session="true" contentType="text/html" pageEncoding="UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="pg" tagdir="/WEB-INF/tags/page" %> + +<%-- + ~ web: content.jsp + ~ XNAT http://www.xnat.org + ~ Copyright (c) 2016, Washington University School of Medicine and Howard Hughes Medical Institute + ~ All Rights Reserved + ~ + ~ Released under the Simplified BSD. + --%> + +<c:set var="redirect"> + <div class="error">Not authorized. Redirecting...</div> + <script> window.location.href = XNAT.url.rootUrl('/') </script> +</c:set> + +<pg:restricted msg="${redirect}"> + + <div id="page-body"> + <div class="pad"> + + <div id="admin-page"> + <header id="content-header"> + <h2 class="pull-left">Plugin Settings</h2> + <div class="clearfix"></div> + </header> + + <!-- Plugin Settings tab container --> + <div id="plugin-settings-tabs"> + + <div class="content-tabs xnat-tab-container"> + + <%-- + <div class="xnat-nav-tabs side pull-left"> + <!-- ================== --> + <!-- Admin tab flippers --> + <!-- ================== --> + </div> + <div class="xnat-tab-content side pull-right"> + <!-- ================== --> + <!-- Admin tab panes --> + <!-- ================== --> + </div> + --%> + + </div> + + </div> + + <c:import url="/xapi/plugins" var="plugins"/> + + <script> + (function(){ + + XNAT.xapi = getObject(XNAT.xapi); + + <c:if test="${not empty plugins}"> + XNAT.xapi.plugins = ${plugins}; + XNAT.data['/xapi/plugins'] = XNAT.xapi.plugins; + </c:if> + + XNAT.data = extend(true, { + plugins: XNAT.xapi.plugins + }, XNAT.data||{}); + + // these properties MUST be set before spawning 'tabs' widgets + XNAT.tabs.container = $('#plugin-settings-tabs').find('div.content-tabs'); + XNAT.tabs.layout = 'left'; + + function pluginTabs(name){ + var tabSpawn = XNAT.spawner.resolve(name + '/siteSettings'); + tabSpawn.render(XNAT.tabs.container, 200) + .fail(function(){ + console.log('"' + name + '" site settings tabs not found'); + }); + return tabSpawn; + } + + // try to get plugin tab Spawner objects + // from url: + // /xapi/spawner/resolve/pluginName/siteSettings + forOwn(XNAT.xapi.plugins, function(name, obj){ + // first try to load admin js file at + // /scripts/xnat-plugins/pluginName/admin.js + //loadjs(XNAT.url.rootUrl('/scripts/xnat-plugins/' + name + '/admin.js'), name); + pluginTabs(name); + }); + + })(); + </script> + + </div> + + </div> + </div> + <!-- /#page-body --> + + <div id="xnat-scripts"></div> + +</pg:restricted> + diff --git a/src/main/webapp/page/admin/plugins/index.jsp b/src/main/webapp/page/admin/plugins/index.jsp new file mode 100644 index 00000000..4ed945e8 --- /dev/null +++ b/src/main/webapp/page/admin/plugins/index.jsp @@ -0,0 +1,20 @@ +<%@ page session="true" contentType="text/html" pageEncoding="UTF-8" language="java" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> +<%@ taglib prefix="pg" tagdir="/WEB-INF/tags/page" %> + +<%-- + ~ web: index.jsp + ~ XNAT http://www.xnat.org + ~ Copyright (c) 2016, Washington University School of Medicine and Howard Hughes Medical Institute + ~ All Rights Reserved + ~ + ~ Released under the Simplified BSD. + --%> + +<pg:wrapper> + <pg:xnat> + + <jsp:include page="content.jsp"/> + + </pg:xnat> +</pg:wrapper> diff --git a/src/main/webapp/page/content.jsp b/src/main/webapp/page/content.jsp index 9994de23..d60e848c 100755 --- a/src/main/webapp/page/content.jsp +++ b/src/main/webapp/page/content.jsp @@ -21,7 +21,7 @@ <div id="page-wrapper"> <div class="pad"> - <div id="page-content">loading...</div> + <div id="page-content"></div> </div> </div> @@ -29,13 +29,13 @@ (function(){ var customPage = XNAT.app.customPage; - var $pageContent = $('#page-content'); + var $pageContent = $('#page-content').html('loading...'); - customPage.getPage(['', '/#'], $pageContent); + customPage.getPage(null, $pageContent); -// window.onhashchange = function(){ -// customPage.getPage('', $pageContent); -// } + // window.onhashchange = function(){ + // customPage.getPage('', $pageContent); + // } })(); </script> diff --git a/src/main/webapp/scripts/globals.js b/src/main/webapp/scripts/globals.js index 4301f3c2..f5748d4c 100644 --- a/src/main/webapp/scripts/globals.js +++ b/src/main/webapp/scripts/globals.js @@ -1209,7 +1209,7 @@ function writeCSS( href ){ function loadCSS( url, parent ){ // use CSS-style selector for 'parent' parent = parent ? document.querySelector(parent) : document.querySelector('head'); - parent.appendChild(scriptElement(url, min, name)); + parent.appendChild(cssElement(url)); } // basic indentation formatting only @@ -1243,8 +1243,14 @@ function prettifyJSON(data, indent) { // call 'test' at 'interval' until it returns true // then execute 'callback' -- basic but useful function waitForIt(interval, test, callback){ + var _test = test; + if (typeof test !== 'function') { + _test = function(){ + return !!test + } + } var waiting = setInterval(function(){ - if (test()) { + if (_test()) { var called = callback(); clearInterval(waiting); return called; diff --git a/src/main/webapp/scripts/xnat/admin/pluginSettings.js b/src/main/webapp/scripts/xnat/admin/pluginSettings.js new file mode 100644 index 00000000..fe547b20 --- /dev/null +++ b/src/main/webapp/scripts/xnat/admin/pluginSettings.js @@ -0,0 +1,89 @@ +/*! + * Plugin site settings functions + */ + +var XNAT = getObject(XNAT); + +(function(factory){ + if (typeof define === 'function' && define.amd) { + define(factory); + } + else if (typeof exports === 'object') { + module.exports = factory(); + } + else { + return factory(); + } +}(function(){ + + var pluginSettings; + + XNAT.admin = + getObject(XNAT.admin); + + XNAT.admin.pluginSettings = pluginSettings = + getObject(XNAT.admin.pluginSettings); + + pluginSettings.check = function(){ + + return XNAT.xhr.get(XNAT.url.restUrl('/xapi/plugins'), function(plugins){ + + console.log('/xapi/plugins response:'); + console.log(plugins); + + var showMenuItem = false; + + if (!isEmpty(plugins)) { + + // calling forOwn() returns the key names + var pluginNames = forOwn(plugins); + + console.log('plugin names:'); + console.log(pluginNames); + + var setPaths = function(names){ + var paths = []; + [].concat(names).forEach(function(name){ + paths.push(name + '/siteSettings'); + // paths.push(name + '/admin'); + }); + return paths; + }; + + var pluginSettingsPaths = setPaths(pluginNames); + + function getPluginSpawnerElements(path){ + var _url = XNAT.url.restUrl('/xapi/spawner/resolve/' + path); + return XNAT.xhr.get(_url); + } + + function lookForSettings(i) { + if (showMenuItem || i === pluginSettingsPaths.length){ + // console.log("couldn't do it"); + return false; + } + // recursively try to get settings at different places + getPluginSpawnerElements(pluginSettingsPaths[i]) + .done(function(){ + showMenuItem = true; + $('#view-plugin-settings').removeClass('hidden'); + }) + .fail(function(){ + lookForSettings(++i) + }); + } + + // do the stuff + lookForSettings(0); + + } + + }); + }; + + // call it. + pluginSettings.check(); + + XNAT.admin.pluginSettings = pluginSettings; + +})); diff --git a/src/main/webapp/scripts/xnat/spawner.js b/src/main/webapp/scripts/xnat/spawner.js index 5bb37654..e8c661fe 100644 --- a/src/main/webapp/scripts/xnat/spawner.js +++ b/src/main/webapp/scripts/xnat/spawner.js @@ -344,8 +344,6 @@ var XNAT = getObject(XNAT); // you can pass a config object as the only argument opts = cloneObject(firstDefined(opts, getObject(nsPath))); - console.log(opts); - var url = opts.url || XNAT.url.restUrl('/xapi/spawner/resolve/' + nsPath); var request = XNAT.xhr.getJSON(extend(true, { diff --git a/src/main/webapp/scripts/xnat/ui/panel.js b/src/main/webapp/scripts/xnat/ui/panel.js index b72e956e..07fa28f9 100644 --- a/src/main/webapp/scripts/xnat/ui/panel.js +++ b/src/main/webapp/scripts/xnat/ui/panel.js @@ -560,7 +560,12 @@ var XNAT = getObject(XNAT || {}); // ajaxConfig.data = JSON.stringify(form2js(this, /[:\[\]]/)); ajaxConfig.data = JSON.stringify(form2js(inputs, ':', false)); ajaxConfig.processData = false; - ajaxConfig.contentType = 'application/json'; + if (opts.contentType === 'text/json') { + ajaxConfig.contentType = opts.contentType; + } + else { + ajaxConfig.contentType = 'application/json'; + } //$.ajax(ajaxConfig); // XNAT.xhr.form($form, ajaxConfig); } diff --git a/src/main/webapp/scripts/xnat/ui/select.js b/src/main/webapp/scripts/xnat/ui/select.js index ef8ef9d8..4da84d36 100644 --- a/src/main/webapp/scripts/xnat/ui/select.js +++ b/src/main/webapp/scripts/xnat/ui/select.js @@ -34,12 +34,24 @@ var XNAT = getObject(XNAT); // as methods and properties to the function select = getObject(XNAT.ui.select || {}); - function addOption(el, opt){ - el.appendChild(spawn('option', extend(true, { - value: opt.value !== undefined ? opt.value : '', - html: opt.html || opt.text || opt.label || opt.value, - selected: opt.selected || false - }, opt.element ))); + function addOption(el, opt, sel){ + var val, txt; + if (typeof opt === 'string') { + val = opt; + txt = opt; + } + else { + val = opt.value !== undefined ? opt.value : ''; + txt = opt.html || opt.text || opt.label || val; + } + var option = spawn('option', extend(true, { + value: val, + html: txt, + selected: val === sel || [].concat(sel).indexOf(val) > -1 || opt.selected || false + }, opt.element, { + //selected: val === sel || [].concat(sel).indexOf(val) > -1 || opt.selected || false + })); + el.appendChild(option); } // generate JUST the options @@ -62,7 +74,7 @@ var XNAT = getObject(XNAT); select.menu = function(config){ var frag = document.createDocumentFragment(), - menu, label; + $menu, menu, label; config = cloneObject(config); @@ -71,22 +83,24 @@ var XNAT = getObject(XNAT); config.id = config.id || toDashed(config.name) || randomID('menu-', false); config.name = config.name || ''; + config.value = config.value !== undefined ? config.value : ''; config.element = extend(true, { id: config.id, name: config.name, - value: config.value !== undefined ? config.value : '', + value: config.value, title: config.title || '' }, config.element); - menu = spawn('select', config.element); + $menu = $.spawn('select', config.element); + menu = $menu[0]; addOption(menu, { html: 'Select' }); if (config.options){ if (Array.isArray(config.options)) { forEach(config.options, function(opt){ - addOption(menu, opt); + addOption(menu, opt, config.value); }) } else { @@ -99,14 +113,15 @@ var XNAT = getObject(XNAT); else { opt = txt; } - addOption(menu, opt); + addOption(menu, opt, config.value); }); } } // force menu change event to select 'selected' option - $(menu).change(); - + $menu.changeVal(config.value); + // $menu.find('[value="' + config.value + '"]').prop('selected', true); + // if there's no label, wrap the // <select> inside a <label> element if (!config.label) { diff --git a/src/main/webapp/scripts/xnat/ui/tabs.js b/src/main/webapp/scripts/xnat/ui/tabs.js index 2305742c..9542a5cc 100755 --- a/src/main/webapp/scripts/xnat/ui/tabs.js +++ b/src/main/webapp/scripts/xnat/ui/tabs.js @@ -50,6 +50,8 @@ var XNAT = getObject(XNAT || {}); tab.group = function(obj){ var id = toDashed(obj.id || obj.name); if (!id) return; // a tab group MUST have an id + // return if the group already exists + if ($('ul#' + id + '.nav.tab-group').length) return; return spawn('ul.nav.tab-group', { id: id }, [ ['li.label', (obj.label || obj.title || obj.text || 'Tab Group')] ]); @@ -194,24 +196,23 @@ var XNAT = getObject(XNAT || {}); // use existing tabs if already present if ($container.find(NAV_TABS).length) { - navTabs = $container.find(NAV_TABS)[0] + $navTabs = $container.find(NAV_TABS); } else { - navTabs = spawn(NAV_TABS); - $container.append(navTabs); + $navTabs = $.spawn(NAV_TABS); + $container.append($navTabs); } + navTabs = $navTabs[0]; // use existing content container if already present if ($container.find(TAB_CONTENT).length) { - tabContent = $container.find(TAB_CONTENT)[0]; + $tabContent = $container.find(TAB_CONTENT); } else { - tabContent = spawn(TAB_CONTENT); - $container.append(tabContent); + $tabContent = $.spawn(TAB_CONTENT); + $container.append($tabContent); } - - $navTabs = $(navTabs); - $tabContent = $(tabContent); + tabContent = $tabContent[0]; layout = obj.layout || tabs.layout || 'left'; diff --git a/src/main/webapp/scripts/xnat/xhr.js b/src/main/webapp/scripts/xnat/xhr.js index 73421959..5f3754f4 100755 --- a/src/main/webapp/scripts/xnat/xhr.js +++ b/src/main/webapp/scripts/xnat/xhr.js @@ -593,11 +593,19 @@ var XNAT = getObject(XNAT||{}), var inputs = $inputs.toArray(); if (/POST|PUT/i.test(opts.method)) { + if ($form.hasAnyClass('json-text text-json')) { + opts.contentType = 'text/json'; + } if ($form.hasClass('json') || /json/i.test(opts.contentType||'')){ // opts.data = formToJSON($form, true); opts.data = JSON.stringify(form2js(inputs, opts.delimiter||opts.delim||':', false)); opts.processData = false; - opts.contentType = 'application/json'; + if (opts.contentType === 'text/json') { + opts.contentType = 'text/plain'; + } + else { + opts.contentType = 'application/json'; + } } else { opts.data = $form.find(':input').not('.ignore').serialize(); diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/Automation.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/Automation.vm new file mode 100644 index 00000000..1396e02f --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/Automation.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 80 --> + +<li><a href="${SITE_ROOT}/app/template/Scripts.vm">Automation</a></li> diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/DataTypes.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/DataTypes.vm new file mode 100644 index 00000000..61664a8a --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/DataTypes.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 50 --> + +<li><a href="${SITE_ROOT}/app/template/XDATScreen_dataTypes.vm">Data Types</a></li> diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/Default.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/Default.vm index 68db2d8e..5757cb5d 100644 --- a/src/main/webapp/xnat-templates/screens/topBar/Administer/Default.vm +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/Default.vm @@ -1,10 +1,82 @@ <!-- Sequence: 10 --> -##<li><a href="/page/admin/">Site Administration</a></li> -<li><a href="${SITE_ROOT}/app/template/Page.vm?view=admin">Site Administration</a></li> -<li><a href="$link.setPage("XDATScreen_admin.vm")">Users</a></li> -<li><a href="$link.setPage("XDATScreen_groups.vm")">Groups</a></li> -<li><a href="$link.setPage("XDATScreen_dataTypes.vm")">Data Types</a></li> -<li><a href="$link.setPage("XDATScreen_email.vm")">Email</a></li> -<li><a href="$link.setPage("XDATScreen_manage_pipeline.vm")">Pipelines</a></li> -<li><a href="$link.setPage("Scripts.vm")">Automation</a></li> -<li><a href="$link.setPage("XDATScreen_admin_options.vm")">More...</a></li> + +<!-- xnat-templates/screens/topBar/Administer/Default.vm --> + +####<li><a href="/page/admin/">Site Administration</a></li> +##<li><a href="${SITE_ROOT}/app/template/Page.vm?view=admin">Site Administration</a></li> +##<li id="view-plugin-settings" class="hidden"><a href="${SITE_ROOT}/app/template/Page.vm?view=admin/plugins">Plugin Settings</a></li> +##<li><a href="$link.setPage("XDATScreen_admin.vm")">Users</a></li> +##<li><a href="$link.setPage("XDATScreen_groups.vm")">Groups</a></li> +##<li><a href="$link.setPage("XDATScreen_dataTypes.vm")">Data Types</a></li> +##<li><a href="$link.setPage("XDATScreen_email.vm")">Email</a></li> +##<li><a href="$link.setPage("XDATScreen_manage_pipeline.vm")">Pipelines</a></li> +##<li><a href="$link.setPage("Scripts.vm")">Automation</a></li> +##<li><a href="$link.setPage("XDATScreen_admin_options.vm")">More...</a></li> +## +##<script src="${SITE_ROOT}/scripts/xnat/admin/pluginSettings.js"></script> +## +##<script> +## XNAT.xhr.get(XNAT.url.restUrl('/xapi/plugins'), function(plugins){ +## +## console.log('/xapi/plugins response'); +## console.log(plugins); +## +## var hideMenuItem = true; +## +## if (!isEmpty(plugins)) { +## +## var setPaths = function(names){ +## var paths = []; +## [].concat(names).forEach(function(name){ +## paths.push(name + '/siteSettings'); +## paths.push(name + '/admin'); +## }); +## return paths; +## }; +## +## // calling forOwn() returns the key names +## var pluginNames = forOwn(plugins); +## var pluginSettingsPaths = setPaths(pluginNames); +## +## function getPluginSpawnerElements(path){ +## var _url = XNAT.url.restUrl('/xapi/spawner/resolve/' + path) +## return XNAT.xhr.get(_url); +## } +## +## function lookForSettings(i) { +## if (i === pluginSettingsPaths.length){ +## // console.log("couldn't do it"); +## return false; +## } +## // recursively try to get settings at different places +## getPluginSpawnerElements(pluginSettingsPaths[i]) +## .done(function(){ +## $('#view-plugin-settings').removeClass('hidden'); +## }) +## .fail(function(){ +## lookForSettings(++i) +## }); +## } +## +## // do the stuff +## lookForSettings(0); +## +##// forOwn(plugins, function(name, obj){ +##// if (hideMenuItem) return; +##// getPluginSpawnerElements(name + '/siteSettings') +##// .done(function(){ +##// showMenuItem = true; +##// $('#view-plugin-settings').removeClass('hidden'); +##// }) +##// .fail(function(){ +##// getPluginSpawnerElements(name + '/admin') +##// .done(function(){ +##// showMenuItem = true; +##// $('#view-plugin-settings').removeClass('hidden'); +##// }) +##// }); +##// }); +## } +## +## }); +##</script> \ No newline at end of file diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/Email.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/Email.vm new file mode 100644 index 00000000..10d03d59 --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/Email.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 60 --> + +<li><a href="${SITE_ROOT}/app/template/XDATScreen_email.vm">Email</a></li> diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/Groups.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/Groups.vm new file mode 100644 index 00000000..0886e2dd --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/Groups.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 40 --> + +<li><a href="${SITE_ROOT}/app/template/XDATScreen_groups.vm">Groups</a></li> diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/More.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/More.vm new file mode 100644 index 00000000..a7af1794 --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/More.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 90 --> + +<li><a href="${SITE_ROOT}/app/template/XDATScreen_admin_options.vm">More...</a></li> diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/Pipelines.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/Pipelines.vm new file mode 100644 index 00000000..2abb6acc --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/Pipelines.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 70 --> + +<li><a href="${SITE_ROOT}/app/template/XDATScreen_manage_pipeline.vm">Pipelines</a></li> diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/PluginSettings.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/PluginSettings.vm new file mode 100644 index 00000000..61631d42 --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/PluginSettings.vm @@ -0,0 +1,5 @@ +<!-- Sequence: 20 --> +<li id="view-plugin-settings" class="hidden"> + <a href="${SITE_ROOT}/app/template/Page.vm?view=admin/plugins">Plugin Settings</a> +</li> +<script src="${SITE_ROOT}/scripts/xnat/admin/pluginSettings.js"></script> \ No newline at end of file diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/SiteAdmin.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/SiteAdmin.vm new file mode 100644 index 00000000..d5b31cee --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/SiteAdmin.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 10 --> +##<li><a href="/page/admin/">Site Administration</a></li> +<li><a href="${SITE_ROOT}/app/template/Page.vm?view=admin">Site Administration</a></li> \ No newline at end of file diff --git a/src/main/webapp/xnat-templates/screens/topBar/Administer/Users.vm b/src/main/webapp/xnat-templates/screens/topBar/Administer/Users.vm new file mode 100644 index 00000000..ebfc04f4 --- /dev/null +++ b/src/main/webapp/xnat-templates/screens/topBar/Administer/Users.vm @@ -0,0 +1,3 @@ +<!-- Sequence: 30 --> + +<li><a href="${SITE_ROOT}/app/template/XDATScreen_admin.vm">Users</a></li> -- GitLab