diff --git a/src/main/webapp/WEB-INF/tags/page/head.tag b/src/main/webapp/WEB-INF/tags/page/head.tag index ecd4589529d2a6947f6dbb6d2d37278751a7b588..67e051f33a773a6ea556ada94b2abe85d57eb0de 100755 --- a/src/main/webapp/WEB-INF/tags/page/head.tag +++ b/src/main/webapp/WEB-INF/tags/page/head.tag @@ -3,8 +3,8 @@ <%@ taglib prefix="pg" tagdir="/WEB-INF/tags/page" %> <%@ attribute name="title" %> -<%@ attribute name="headTop" fragment="true" %> -<%@ attribute name="headBottom" fragment="true" %> +<%@ attribute name="headTop" %> +<%@ attribute name="headBottom" %> <head> diff --git a/src/main/webapp/WEB-INF/tags/page/restricted.tag b/src/main/webapp/WEB-INF/tags/page/restricted.tag index c1fa1e79dd38f853ad09f75dfb3c27e0ebf85706..dac0c39506843ab55776701d2b49337bd20aa8e5 100644 --- a/src/main/webapp/WEB-INF/tags/page/restricted.tag +++ b/src/main/webapp/WEB-INF/tags/page/restricted.tag @@ -6,6 +6,14 @@ <%-- restricts access to only admin users --%> +<c:if test="${empty hasInit}"> + <pg:init> + <c:if test="${empty hasVars}"> + <pg:jsvars/> + </c:if> + </pg:init> +</c:if> + <c:choose> <c:when test="${isAdmin == true}"> diff --git a/src/main/webapp/WEB-INF/tags/page/xnat.tag b/src/main/webapp/WEB-INF/tags/page/xnat.tag index 2aff8706a75b7a70211f1ba68747e1ee2ad87b5e..5265f77e2f44a72e81258b6dcff6048de590fc12 100644 --- a/src/main/webapp/WEB-INF/tags/page/xnat.tag +++ b/src/main/webapp/WEB-INF/tags/page/xnat.tag @@ -76,8 +76,6 @@ <script src="${_siteRoot}/scripts/lib/js.cookie.js"></script> <script src="${_siteRoot}/scripts/lib/yamljs/dist/yaml.js"></script> - - <%--<script src="${_siteRoot}/scripts/yui/build/yahoo-dom-event/yahoo-dom-event.js"></script>--%> <%--<script src="${_siteRoot}/scripts/yui/build/event/event-min.js"></script>--%> <%--<script src="${_siteRoot}/scripts/yui/build/container/container-min.js"></script>--%> @@ -98,9 +96,6 @@ <%--<script src="${_siteRoot}/scripts/LeftBarTreeView.js"></script>--%> <%--<script src="${_siteRoot}/scripts/justification/justification.js"></script>--%> - - - <!-- XNAT utility functions --> <script src="${_siteRoot}/scripts/utils.js"></script> @@ -218,72 +213,71 @@ ${headBottom} ${bodyTop} -<div id="page_wrapper"> - - <div id="user_bar"> - <div class="inner"> - <img id="attention_icon" src="${_siteRoot}/images/attention.png" style="display:none;" alt="attention needed - click for more info" title="attention needed - click for more info"> +<div id="user_bar"> + <div class="inner"> + <img id="attention_icon" src="${_siteRoot}/images/attention.png" style="display:none;" alt="attention needed - click for more info" title="attention needed - click for more info"> <span id="user_info">Logged in as: <a href="${_siteRoot}/app/template/XDATScreen_UpdateUser.vm">${_user}</a> <b>|</b> <span class="tip_icon" style="margin-right:3px;left:2px;top:3px;"> <span class="tip shadowed" style="top:20px;z-index:10000;white-space:normal;left:-150px;width:300px;background-color:#ffc;"> - Your XNAT session will auto-logout after a certain period of inactivity. + Your XNAT session will auto-logout after a certain period of inactivity. You can reset the timer without reloading thepage by clicking "renew." </span> </span> - Auto-logout in: + Auto-logout in: <b id="timeLeft">-:--:--</b> - <a id="timeLeftRenew" href="#!">renew</a> - <b>|</b> + <b>|</b> <a id="logout_user" href="${_siteRoot}/app/action/LogoutUser">Logout</a> </span> - <%--<script type="text/javascript">--%> - <%--$('#timeLeftRenew').click(XNAT.app.timeout.handleOk);--%> - <%--Cookies.set('guest', 'false', {path: '/'});--%> - <%--</script>--%> - <div class="clear"></div> - </div> - </div><!-- /user_bar --> - - - <div id="main_nav"> - - <ul class="nav"> - <!-- Sequence: 10 --> - <!-- allowGuest: true --> - <li> - <a id="nav-home" title="Home" href="${_siteRoot}/"> </a> - <script> - $('#nav-home').css({ - width: '30px', - backgroundImage: "url('${_siteRoot}/images/xnat-nav-logo-white-lg.png')", - backgroundRepeat: 'no-repeat', - backgroundSize: '32px', - backgroundPosition: 'center' - }); - </script> - </li> - <!-- Sequence: 20 --> - <li class="more"><a href="#new">New</a> - <ul class="" style="display: none;"> - <!-- Sequence: 10 --> - <li><a href="${_siteRoot}/app/template/XDATScreen_add_xnat_projectData.vm">Project</a></li> - <li><a href="${_siteRoot}/app/action/XDATActionRouter/xdataction/edit/search_element/xnat%3AsubjectData">Subject</a></li> - <li><a href="${_siteRoot}/app/template/XDATScreen_add_experiment.vm">Experiment</a></li> - </ul> - </li> - <!-- Sequence: 30 --> - <li class="more"><a href="#upload">Upload</a> - <ul> - <!-- Sequence: 10 --> - <!-- Upload/Default --> - <li><a href="${_siteRoot}/app/template/LaunchUploadApplet.vm">Images</a></li> - <li><a href="${_siteRoot}/app/template/XMLUpload.vm">XML</a></li> - <li><a href="${_siteRoot}/app/template/XDATScreen_uploadCSV.vm">Spreadsheet</a></li> - <li><a href="${_siteRoot}/app/template/XDATScreen_prearchives.vm">Go to prearchive</a></li> - </ul> - </li> + <%--<script type="text/javascript">--%> + <%--$('#timeLeftRenew').click(XNAT.app.timeout.handleOk);--%> + <%--Cookies.set('guest', 'false', {path: '/'});--%> + <%--</script>--%> + <div class="clear"></div> + </div> +</div><!-- /user_bar --> - <c:if test="${isAdmin == true}"> +<div id="main_nav"> + <div class="inner"> + + <ul class="nav"> + <!-- Sequence: 10 --> + <!-- allowGuest: true --> + <li> + <a id="nav-home" title="Home" href="${_siteRoot}/"> </a> + <script> + $('#nav-home').css({ + width: '30px', + backgroundImage: "url('${_siteRoot}/images/xnat-nav-logo-white-lg.png')", + backgroundRepeat: 'no-repeat', + backgroundSize: '32px', + backgroundPosition: 'center' + }); + </script> + </li> + <!-- Sequence: 20 --> + <li class="more"><a href="#new">New</a> + <ul class="" style="display: none;"> + <!-- Sequence: 10 --> + <li><a href="${_siteRoot}/app/template/XDATScreen_add_xnat_projectData.vm">Project</a></li> + <li><a href="${_siteRoot}/app/action/XDATActionRouter/xdataction/edit/search_element/xnat:subjectData">Subject</a></li> + <li><a href="${_siteRoot}/app/template/XDATScreen_add_experiment.vm">Experiment</a></li> + </ul> + </li> + <!-- Sequence: 30 --> + <li class="more"><a href="#upload">Upload</a> + <ul> + <!-- Sequence: 10 --> + <!-- Upload/Default --> + <li><a href="${_siteRoot}/app/template/LaunchUploadApplet.vm">Images</a></li> + <li><a href="${_siteRoot}/app/template/XMLUpload.vm">XML</a></li> + <li><a href="${_siteRoot}/app/template/XDATScreen_uploadCSV.vm">Spreadsheet</a></li> + <li><a href="${_siteRoot}/app/template/XDATScreen_prearchives.vm">Go to prearchive</a></li> + </ul> + </li> + + + <c:if test="${isAdmin == true}"> <!-- Sequence: 40 --> <li class="more"><a href="#adminbox">Administer</a> <ul> @@ -298,222 +292,229 @@ ${bodyTop} <li><a href="${_siteRoot}/app/template/XDATScreen_admin_options.vm">More...</a></li> </ul> </li> - </c:if> - - - <!-- Title: Tools --> - <!-- Sequence: 50 --> - <!-- allowGuest: true --> - - <li class="more"><a href="#tools">Tools</a> - <ul> - <!-- Sequence: 10 --> - <!-- allowGuest: true --> - <li><a href="https://wiki.xnat.org/display/XNAT16/XNAT+Desktop" target="_blank">XNAT Desktop (XND)</a></li> - <li><a href="http://nrg.wustl.edu/projects/DICOM/DicomBrowser.jsp" target="_blank">DICOM Browser</a></li> - <li><a href="https://wiki.xnat.org/display/XNAT16/XNAT+Client+Tools" target="_blank">Command Prompt Tools</a></li> - </ul> - </li> - <!-- Sequence: 60 --> - <li class="more"><a href="#help">Help</a> - <ul class="" style="display: none;"> - <!-- Sequence: 10 --> - <!-- Home/Default --> - <li><a href="${_siteRoot}/app/template/ReportIssue.vm">Report a Problem</a></li> - <li><a href="http://wiki.xnat.org/display/XNAT16/Home" target="_blank">Documentation</a></li> - </ul> - </li> - </ul> - - <!-- search script --> - <script type="text/javascript"> - <!-- - function DefaultEnterKey(e, button){ - var keynum, keychar, numcheck; - - if (window.event) // IE - { - keynum = e.keyCode; - if (keynum == 13) { - submitQuickSearch(); - return true; - } - } - else if (e) // Netscape/Firefox/Opera - { - keynum = e.which; - if (keynum == 13) { - submitQuickSearch(); - return false; - } + </c:if> + + + <!-- Title: Tools --> + <!-- Sequence: 50 --> + <!-- allowGuest: true --> + + <li class="more"><a href="#tools">Tools</a> + <ul> + <!-- Sequence: 10 --> + <!-- allowGuest: true --> + <li><a href="https://wiki.xnat.org/display/XNAT16/XNAT+Desktop" target="_blank">XNAT Desktop (XND)</a></li> + <li><a href="http://nrg.wustl.edu/projects/DICOM/DicomBrowser.jsp" target="_blank">DICOM Browser</a></li> + <li><a href="https://wiki.xnat.org/display/XNAT16/XNAT+Client+Tools" target="_blank">Command Prompt Tools</a></li> + </ul> + </li> + <!-- Sequence: 60 --> + <li class="more"><a href="#help">Help</a> + <ul class="" style="display: none;"> + <!-- Sequence: 10 --> + <!-- Home/Default --> + <li><a href="${_siteRoot}/app/template/ReportIssue.vm">Report a Problem</a></li> + <li><a href="http://wiki.xnat.org/display/XNAT16/Home" target="_blank">Documentation</a></li> + </ul> + </li> + </ul> + + <!-- search script --> + <script type="text/javascript"> + <!-- + function DefaultEnterKey(e, button){ + var keynum, keychar, numcheck; + + if (window.event) // IE + { + keynum = e.keyCode; + if (keynum == 13) { + submitQuickSearch(); + return true; } - return true; } - - function submitQuickSearch(){ - concealContent(); - if (document.getElementById('quickSearchForm').value != "") - document.getElementById('quickSearchForm').submit(); + else if (e) // Netscape/Firefox/Opera + { + keynum = e.which; + if (keynum == 13) { + submitQuickSearch(); + return false; + } } + return true; + } - //--> - </script> - <!-- end search script --> + function submitQuickSearch(){ + concealContent(); + if (document.getElementById('quickSearchForm').value != "") + document.getElementById('quickSearchForm').submit(); + } - <style type="text/css"> - #quickSearchForm .chosen-results { - max-height: 500px; - } + //--> + </script> + <!-- end search script --> + + <style type="text/css"> + #quickSearchForm .chosen-results { + max-height: 500px; + } + + #quickSearchForm .chosen-results li { + padding-right: 20px; + white-space: nowrap; + } + + #quickSearchForm .chosen-container .chosen-drop { + width: auto; + min-width: 180px; + max-width: 360px; + } + + #quickSearchForm .chosen-container .chosen-drop .divider { + padding: 0; + overflow: hidden; + } + </style> + + <form id="quickSearchForm" method="post" action="${_siteRoot}/app/action/QuickSearchAction"> + <select id="stored-searches" data-placeholder="Stored Searches" style="display: none;"> + <option></option> + <optgroup> + <option value="${_siteRoot}/app/template/XDATScreen_search_wizard1.vm">Advanced Search…</option> + </optgroup> + <optgroup class="stored-search-list"> + <option disabled="">(no stored searches)</option> + <!-- stored searches will show up here --> + </optgroup> + </select> + <input id="searchValue" class="clean" name="searchValue" type="text" maxlength="40" size="20" value=""> + <button type="button" id="search_btn" class="btn2" onclick="submitQuickSearch();">Go</button> + + <script> + + $('#searchValue').each(function(){ + var _this = this; + _this.value = _this.value || 'search'; + $(_this).focus(function(){ + $(_this).removeClass('clean'); + if (!_this.value || _this.value === 'search') { + _this.value = ''; + } + }) + }); - #quickSearchForm .chosen-results li { - padding-right: 20px; - white-space: nowrap; - } + $('#stored-searches').on('change', function(){ + if (this.value) { + window.location.href = this.value; + } + }).chosen({ + width: '150px', + disable_search_threshold: 9, + inherit_select_classes: true, + placeholder_text_single: 'Stored Searches', + search_contains: true + }); - #quickSearchForm .chosen-container .chosen-drop { - width: auto; - min-width: 180px; - max-width: 360px; - } + </script> + </form> - #quickSearchForm .chosen-container .chosen-drop .divider { - padding: 0; - overflow: hidden; - } - </style> - - <form id="quickSearchForm" method="post" action="${_siteRoot}/app/action/QuickSearchAction"> - <select id="stored-searches" data-placeholder="Stored Searches" style="display: none;"> - <option></option> - <optgroup> - <option value="${_siteRoot}/app/template/XDATScreen_search_wizard1.vm">Advanced Search…</option> - </optgroup> - <optgroup class="stored-search-list"> - <option disabled="">(no stored searches)</option> - <!-- stored searches will show up here --> - </optgroup> - </select> - <input id="searchValue" class="clean" name="searchValue" type="text" maxlength="40" size="20" value=""> - <button type="button" id="search_btn" class="btn2" onclick="submitQuickSearch();">Go</button> + </div> + <!-- /.inner --> - <script> - $('#searchValue').each(function(){ - var _this = this; - _this.value = _this.value || 'search'; - $(_this).focus(function(){ - $(_this).removeClass('clean'); - if (!_this.value || _this.value === 'search') { - _this.value = ''; - } - }) - }); - - $('#stored-searches').on('change', function(){ - if (this.value) { - window.location.href = this.value; - } - }).chosen({ - width: '150px', - disable_search_threshold: 9, - inherit_select_classes: true, - placeholder_text_single: 'Stored Searches', - search_contains: true - }); - </script> - </form> +</div> +<!-- /#main_nav --> - </div> - <!-- /main_nav --> +<!-- main_nav interactions --> +<script type="text/javascript"> - <!-- main_nav interactions --> - <script type="text/javascript"> + (function(){ - (function(){ + // cache it + var main_nav$ = jq('#main_nav ul.nav'); - // cache it - var main_nav$ = jq('#main_nav > ul'); - - var body$ = jq('body'); + var body$ = jq('body'); - var cover_up_count = 1; + var cover_up_count = 1; - function coverApplet(el$){ - var cover_up_id = 'cover_up' + cover_up_count++; - var jqObjPos = el$.offset(), + function coverApplet(el$){ + var cover_up_id = 'cover_up' + cover_up_count++; + var jqObjPos = el$.offset(), jqObjLeft = jqObjPos.left, jqObjTop = jqObjPos.top, jqObjMarginTop = el$.css('margin-top'), jqObjWidth = el$.outerWidth() + 4, jqObjHeight = el$.outerHeight() + 2; - el$.before('<iframe id="' + cover_up_id + '" class="applet_cover_up" src="about:blank" width="' + jqObjWidth + '" height="' + jqObjHeight + '"></iframe>'); - - jq('#' + cover_up_id).css({ - display: 'block', - position: 'fixed', - width: jqObjWidth, - height: jqObjHeight, - marginTop: jqObjMarginTop, - left: jqObjLeft, - top: jqObjTop, - background: 'transparent', - border: 'none', - outline: 'none' - }); - } + el$.before('<iframe id="' + cover_up_id + '" class="applet_cover_up" src="about:blank" width="' + jqObjWidth + '" height="' + jqObjHeight + '"></iframe>'); + + jq('#' + cover_up_id).css({ + display: 'block', + position: 'fixed', + width: jqObjWidth, + height: jqObjHeight, + marginTop: jqObjMarginTop, + left: jqObjLeft, + top: jqObjTop, + background: 'transparent', + border: 'none', + outline: 'none' + }); + } - function unCoverApplets(el$){ - el$.prev('iframe.applet_cover_up').detach(); - } + function unCoverApplets(el$){ + el$.prev('iframe.applet_cover_up').detach(); + } - function fadeInNav(el$){ + function fadeInNav(el$){ // el$.stop('clearQueue','gotoEnd'); - el$.find('> ul').show().addClass('open'); - } + el$.find('> ul').show().addClass('open'); + } - function fadeOutNav(el$){ + function fadeOutNav(el$){ // el$.stop('clearQueue','gotoEnd'); - el$.find('> ul').hide().removeClass('open'); - } - - // give menus with submenus a class of 'more' - main_nav$.find('li ul, li li ul').closest('li').addClass('more'); - main_nav$.find('li li ul').addClass('subnav'); - - // no fancy fades on hover - main_nav$.find('li.more').on('mouseover', - function(){ - var li$ = $(this); - fadeInNav(li$); - //jq('#main_nav li').removeClass('open'); - li$.find('ul.subnav').each(function(){ - var sub$ = $(this); - var offsetL = sub$.closest('ul').outerWidth(); - sub$.css({'left': offsetL + -25}) - }); - if (body$.hasClass('applet')) { - coverApplet(li$.find('> ul')); - } + el$.find('> ul').hide().removeClass('open'); + } + + // give menus with submenus a class of 'more' + main_nav$.find('li ul, li li ul').closest('li').addClass('more'); + main_nav$.find('li li ul').addClass('subnav'); + + // no fancy fades on hover + main_nav$.find('li.more').on('mouseover', + function(){ + var li$ = $(this); + fadeInNav(li$); + //jq('#main_nav li').removeClass('open'); + li$.find('ul.subnav').each(function(){ + var sub$ = $(this); + var offsetL = sub$.closest('ul').outerWidth(); + sub$.css({'left': offsetL + -25}) + }); + if (body$.hasClass('applet')) { + coverApplet(li$.find('> ul')); } - ).on('mouseout', - function(){ - var li$ = $(this); - fadeOutNav(li$); - if (body$.hasClass('applet')) { - unCoverApplets(li$.find('> ul')); - } + } + ).on('mouseout', + function(){ + var li$ = $(this); + fadeOutNav(li$); + if (body$.hasClass('applet')) { + unCoverApplets(li$.find('> ul')); } - ); + } + ); - // clicking the "Logout" link sets the warning bar cookie to 'OPEN' so it's available if needed on next login - jq('#logout_user').click(function(){ - Cookies.set('WARNING_BAR', 'OPEN', {path: '/'}); - Cookies.set('NOTIFICATION_MESSAGE', 'OPEN', {path: '/'}); - }); + // clicking the "Logout" link sets the warning bar cookie to 'OPEN' so it's available if needed on next login + jq('#logout_user').click(function(){ + Cookies.set('WARNING_BAR', 'OPEN', {path: '/'}); + Cookies.set('NOTIFICATION_MESSAGE', 'OPEN', {path: '/'}); + }); - })(); - </script> - <!-- end main_nav interactions --> + })(); +</script> +<!-- end main_nav interactions --> + +<div id="page_wrapper"> <div id="header" class="main_header"> <div class="pad"> diff --git a/src/main/webapp/page/admin/content.jsp b/src/main/webapp/page/admin/content.jsp index e8ea27c257713ac42cebc5ace8025692fff3e852..c4eaa07b2f548b70ba47bcec4034bca7d0244046 100755 --- a/src/main/webapp/page/admin/content.jsp +++ b/src/main/webapp/page/admin/content.jsp @@ -31,6 +31,7 @@ </div> <script src="${sessionScope.siteRoot}/scripts/lib/jquery-plugins/jquery.form.js"></script> + <script src="${sessionScope.siteRoot}/scripts/lib/yamljs/dist/yaml.js"></script> <c:import url="/xapi/siteConfig" var="siteConfig"/> @@ -38,9 +39,12 @@ XNAT.data = extend({}, XNAT.data, { siteConfig: ${siteConfig} }); + // get rid of the 'targetSource' property + delete XNAT.data.siteConfig.targetSource; </script> <script src="${sessionScope.siteRoot}/scripts/xnat/ui/templates.js"></script> + <script src="${sessionScope.siteRoot}/scripts/xnat/spawner.js"></script> <script src="${sessionScope.siteRoot}/page/admin/tabs.js"></script> </div> diff --git a/src/main/webapp/page/admin/data/config/site-admin-sample-new.yaml b/src/main/webapp/page/admin/data/config/site-admin-sample-new.yaml index 2cc8643fd85e5f95bf1db67d1a98e28914b4bccd..869eff80a5d00b4879efad14e962f75d15cc5232 100644 --- a/src/main/webapp/page/admin/data/config/site-admin-sample-new.yaml +++ b/src/main/webapp/page/admin/data/config/site-admin-sample-new.yaml @@ -20,7 +20,7 @@ siteAdmin: label: Site Setup group: xnatSetup active: true - config: + element: data: foo: bar contains: panels # the value for 'contains' can be a custom name for 'contents' @@ -33,9 +33,10 @@ siteAdmin: label: Site Information method: POST action: /xapi/siteConfig/batch + contentType: application/json load: data: XNAT.data.siteConfig - + refresh: /xapi/siteConfig # url to use to get fresh data (uses GET) contents: # panel input @@ -45,6 +46,8 @@ siteAdmin: id: side-id label: Site ID value: XNAT + load: + url: /xapi/siteConfig/siteId description: > The id used to refer to this site (also used to generate ids). The Site ID must start with a letter and contain only letters, numbers and underscores. It should be a short, @@ -122,11 +125,15 @@ siteAdmin: emailServerSettings: kind: panel.form method: POST - action: /xapi/notifications/all +# action: /xapi/notifications/smtp + action: /xapi/siteConfig/smtpServer +# action: '#@' # this character combo means submit each item individually + contentType: json load: # load data - url: /xapi/siteConfig -# method: GET # defaults to GET if not set - prop: smtpServer # which root property? gets the root object if not set +# refresh: /xapi/siteConfig/smtpServer + url: /xapi/siteConfig/smtpServer + method: GET # defaults to GET if not set +# prop: smtpServer # which root property? gets the root object if not set # data: XNAT.data.siteConfig.smtpServer name: emailServerSettings label: Mail Server Settings @@ -153,7 +160,6 @@ siteAdmin: kind: panel.input.text name: username label: Username - url: /xapi/notifications/username value: '' element: placeholder: admin@localhost @@ -167,10 +173,12 @@ siteAdmin: name: protocol label: Protocol value: '' - #data: - #get: GET|/xapi/siteConfig|smtpServer.protocol - #set: POST|/xapi/notifications/protocol - # subhead breaks up panel items +# data: +# get: GET|/xapi/siteConfig|smtpServer.protocol +# set: POST|/xapi/notifications/protocol + +# subhead breaks up panel items + mailServerProperties: kind: panel.subhead name: mailServerProperties @@ -179,13 +187,13 @@ siteAdmin: kind: panel.input.checkbox name: mail.smtp.auth label: SMTP Auth? - #value: true + value: true checked: true smtpStartTls: kind: panel.input.checkbox name: mail.smtp.starttls.enable label: Smart TLS? - #value: true + value: true checked: true smtpSSLTrust: kind: panel.input.text @@ -221,6 +229,7 @@ siteAdmin: b: html: B selected: true + sectionA: kind: panel.section element: diff --git a/src/main/webapp/page/admin/site-config/content.jsp b/src/main/webapp/page/admin/site-config/content.jsp new file mode 100644 index 0000000000000000000000000000000000000000..9103383d7f304d3b10f1e109c1b6e92bcd9a2513 --- /dev/null +++ b/src/main/webapp/page/admin/site-config/content.jsp @@ -0,0 +1,125 @@ +<%@ 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" %> + +<c:if test="${empty hasInit}"> + <pg:init> + <c:if test="${empty hasVars}"> + <pg:jsvars/> + </c:if> + </pg:init> +</c:if> + +<c:set var="_msg"> + Nope. +</c:set> + +<pg:restricted msg="${_msg}"> + + <c:import url="/xapi/siteConfig" var="siteConfig"/> + + <script> + XNAT.data = extend({}, XNAT.data, { + siteConfig: ${siteConfig} + }); + // get rid of the 'targetSource' property + delete XNAT.data.siteConfig.targetSource; + </script> + + <div id="page-body"> + <div class="pad" style="padding:20px;"> + + <header id="content-header"> + <h2 class="pull-left">XNAT Site Config Output</h2> + <div class="clear"></div> + </header> + + <hr class="light"> + + <div class="panel panel-default"> + <div class="panel-heading"> + <h3 class="panel-title">View Site Config Items</h3> + </div> + <div class="panel-body"> + <div class="panel-element"> + <label for="select-site-config-item" class="element-label">Select a property</label> + <div class="element-wrapper"> + + <select id="select-site-config-item" style="width:350px;"> + <option value="!"> </option> + </select> + + <br><br> + + <textarea id="site-config-item" class="mono" style="width:400px;height:200px;"></textarea> + + <hr class="light"> + + <button type="button" id="show-site-config-json">Show Site Config JSON</button> + + <form method="" action=""></form> + <div class="description"></div> + + </div> + </div> + </div> + <div class="hidden"></div> + </div> + + + </div> + </div> + + <script> + (function(){ + + var siteConfigObj = XNAT.data.siteConfig; + var $siteConfigSelect = $('#select-site-config-item'); + var siteConfigItems = ''; + + // populate the menu + forOwn(siteConfigObj, function(prop, val){ + // having trouble with objects right now + // if (isPlainObject(val)) return; + siteConfigItems += ('<option value="' + prop + '">' + prop + '</div> \n'); + }); + + $siteConfigSelect.append(siteConfigItems); + + // select an item to show in the textarea + $siteConfigSelect.on('change', function(){ + if (this.value === '!') return false; + var val = siteConfigObj[this.value]; + if (isPlainObject(val) || Array.isArray(val)) { + val = JSON.stringify(val, null, 4); + } + $('#site-config-item').text(val); + // don't need to do a REST call because we already have the object +// $.get(XNAT.url.restUrl('/xapi/siteConfig/' + this.value), function(data){ +// $('#site-config-item').val(data) +// }); + }); + + // show the whole siteConfig object in an xmodal dialog + $('#show-site-config-json').click(function(){ + xmodal.open({ + size: 'large', + minWidth: 800, + minHeight: '90%', + //width: 600, + //height: 500, + maximize: true, + title: 'Site Config JSON', + content: prettifyJSON(siteConfigObj) + }); + }); + + $(function(){ + $siteConfigSelect.chosen(); + }) + + })(); + </script> + +</pg:restricted> + diff --git a/src/main/webapp/page/admin/site-config/index.jsp b/src/main/webapp/page/admin/site-config/index.jsp new file mode 100644 index 0000000000000000000000000000000000000000..9acf00fb6d9b9723cc42474f69693de4dca8964d --- /dev/null +++ b/src/main/webapp/page/admin/site-config/index.jsp @@ -0,0 +1,11 @@ +<%@ page session="true" contentType="text/html" pageEncoding="UTF-8" language="java" %> +<%@ taglib prefix="pg" tagdir="/WEB-INF/tags/page" %> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> + +<pg:wrapper> + <pg:xnat> + + <jsp:include page="content.jsp"/> + + </pg:xnat> +</pg:wrapper> diff --git a/src/main/webapp/page/admin/site-config/siteConfig.js b/src/main/webapp/page/admin/site-config/siteConfig.js new file mode 100644 index 0000000000000000000000000000000000000000..8f7b17c5b26fa51367ebeb531b350b3cc8fec8e4 --- /dev/null +++ b/src/main/webapp/page/admin/site-config/siteConfig.js @@ -0,0 +1,63 @@ +// prepare the form when the DOM is ready +$(document).ready(function() { + var options = { + target: '#output2', // target element(s) to be updated with server response + beforeSubmit: showRequest, // pre-submit callback + success: showResponse // post-submit callback + + // other available options: + //url: url // override for form's 'action' attribute + //type: type // 'get' or 'post', override for form's 'method' attribute + //dataType: null // 'xml', 'script', or 'json' (expected server response type) + //clearForm: true // clear all form fields after successful submit + //resetForm: true // reset the form after successful submit + + // $.ajax options can be used here too, for example: + //timeout: 3000 + }; + + // bind to the form's submit event + $('#myForm2').submit(function() { + // inside event callbacks 'this' is the DOM element so we first + // wrap it in a jQuery object and then invoke ajaxSubmit + $(this).ajaxSubmit(options); + + // !!! Important !!! + // always return false to prevent standard browser submit and page navigation + return false; + }); +}); + +// pre-submit callback +function showRequest(formData, jqForm, options) { + // formData is an array; here we use $.param to convert it to a string to display it + // but the form plugin does this for you automatically when it submits the data + var queryString = $.param(formData); + + // jqForm is a jQuery object encapsulating the form element. To access the + // DOM element for the form do this: + // var formElement = jqForm[0]; + + alert('About to submit: \n\n' + queryString); + + // here we could return false to prevent the form from being submitted; + // returning anything other than false will allow the form submit to continue + return true; +} + +// post-submit callback +function showResponse(responseText, statusText, xhr, $form) { + // for normal html responses, the first argument to the success callback + // is the XMLHttpRequest object's responseText property + + // if the ajaxSubmit method was passed an Options Object with the dataType + // property set to 'xml' then the first argument to the success callback + // is the XMLHttpRequest object's responseXML property + + // if the ajaxSubmit method was passed an Options Object with the dataType + // property set to 'json' then the first argument to the success callback + // is the json data object returned by the server + + alert('status: ' + statusText + '\n\nresponseText: \n' + responseText + + '\n\nThe output div should have already been updated with the responseText.'); +} diff --git a/src/main/webapp/page/admin/spawner/content.jsp b/src/main/webapp/page/admin/spawner/content.jsp index 9fbb0afce888f78c1c58dc0062e0c44648515d86..11d0a5b141e0c80ea2f208fa88cc6a09cb5c9f94 100644 --- a/src/main/webapp/page/admin/spawner/content.jsp +++ b/src/main/webapp/page/admin/spawner/content.jsp @@ -3,14 +3,6 @@ <%@ taglib prefix="pg" tagdir="/WEB-INF/tags/page" %> <%--<%@ taglib prefix="sp" tagdir="/WEB-INF/tags/spawner" %>--%> - <c:if test="${empty hasInit}"> - <pg:init> - <c:if test="${empty hasVars}"> - <pg:jsvars/> - </c:if> - </pg:init> - </c:if> - <c:set var="MSG"> No spawning allowed. </c:set> diff --git a/src/main/webapp/scripts/xnat/ui/panel.js b/src/main/webapp/scripts/xnat/ui/panel.js index cd0ab62d195ffc0b7c4aff44c789e0a3a999c720..1675c7a054beb554aaebf7f9ae2675eb99678f99 100644 --- a/src/main/webapp/scripts/xnat/ui/panel.js +++ b/src/main/webapp/scripts/xnat/ui/panel.js @@ -16,7 +16,7 @@ var XNAT = getObject(XNAT || {}); XNAT.ui.panel = panel = getObject(XNAT.ui.panel || {}); - + // add new element class without destroying existing class function addClassName(el, newClass){ el.className = [].concat(el.className||[], newClass).join(' ').trim(); @@ -33,7 +33,7 @@ var XNAT = getObject(XNAT || {}); } panel.init = function panelInit(opts){ - + opts = getObject(opts); opts.element = opts.element || opts.config || {}; @@ -52,7 +52,7 @@ var XNAT = getObject(XNAT || {}); (hideFooter ? ['div.hidden'] : ['div.panel-footer', opts.footer]) ]); - + // add an id to the outer panel element if present if (opts.id || opts.element.id) { _panel.id = (opts.id || opts.element.id) + '-panel'; @@ -118,7 +118,14 @@ var XNAT = getObject(XNAT || {}); } // find all form inputs with a name attribute $$(form).find(':input[name]').each(function(){ - $(this).changeVal(dataObj[this.name]||''); + var val = ''; + if (Array.isArray(dataObj)) { + val = dataObj.join(', '); + } + else { + val = /string|number/i.test(typeof dataObj) ? dataObj : dataObj[this.name] || ''; + } + $(this).changeVal(val); }); if (xmodal && xmodal.loading && xmodal.loading.close){ xmodal.loading.close(); @@ -140,11 +147,26 @@ var XNAT = getObject(XNAT || {}); // need a form to put the data into if (!obj.form) return; + // // if there's a 'refresh' url, make that obj.url + // if (obj.refresh) obj.url = obj.refresh; + // if we pass data in a 'data' property, just use that // to avoid doing a server request - if (obj.data) { - setValues(obj.form, eval(obj.data)); + if (obj.data && !obj.url) { + if (Array.isArray(obj.data)) { + obj.data = obj.data[0]; + } + else { + try { + obj.data = eval(obj.data); + } + catch (e) { + if (console && console.log) console.log(e); + obj.data = '' + } + } + setValues(obj.form, obj.data); return obj.form; } @@ -187,12 +209,13 @@ var XNAT = getObject(XNAT || {}); // loadData(opts.load); //} - // click 'Discard Changes' butotn to reload data + // click 'Discard Changes' button to reload data _resetBtn.onclick = function(){ xmodal.loading.open(); + opts.load.url = opts.load.refresh; loadData(opts.load); }; - + // intercept the form submit to do it via REST instead $(_formPanel).on('submit', function(e){ @@ -218,19 +241,63 @@ var XNAT = getObject(XNAT || {}); }; - $(this).ajaxSubmit({ - success: function(){ + function formToJSON(form){ + var json = {}; + $$(form).serializeArray().forEach(function(item) { + if (typeof json[item.name] == 'undefined') { + json[item.name] = item.value || ''; + } + else { + json[item.name] = [].concat(json[item.name], item.value||[]) ; + } + }); + return json; + } + + var ajaxConfig = { + method: opts.method, + url: this.action, + success: function(data){ + var obj = {}; + // if a data object is returned, + // just use that + if (data) { + // wrap the returned data in an array so the + // loadData() function handles it properly + obj.data = [data]; + } + else { + obj.url = opts.refresh; + } xmodal.loading.close(); xmodal.message('Data saved successfully.', { - action: loadData() + action: loadData(obj) }); } - }); + }; + + // if (!/form/i.test(opts.contentType||'')) { + // ajaxConfig.contentType = opts.contentType; + // } + + if (/json/i.test(opts.contentType||'')){ + ajaxConfig.data = JSON.stringify(formToJSON(this)); + ajaxConfig.processData = false; + ajaxConfig.contentType = 'application/json'; + $.ajax(ajaxConfig); + } + else { + // ajaxConfig.data = $(this).serialize(); + // $.ajax(ajaxConfig); + $(this).ajaxSubmit(ajaxConfig); + } + + // $.ajax(ajaxConfig); return false; }); - + // this object is returned to the XNAT.spawner() method return { load: loadData, @@ -282,13 +349,13 @@ var XNAT = getObject(XNAT || {}); } }; - + panel.subhead = function(opts){ opts = getObject(opts); opts.html = opts.html || opts.text || opts.label; - return XNAT.ui.template.panelSubhead(opts).spawned; + return XNAT.ui.template.panelSubhead(opts).spawned; }; - + // return a generic panel 'section' panel.section = function(opts){ @@ -297,23 +364,23 @@ var XNAT = getObject(XNAT || {}); opts = getObject(opts); opts.element = opts.element || opts.config || {}; opts.header = opts.header || opts.label || opts.title || ''; - + if (opts.header) { _inner.push(['header.section-header', opts.header]); } - + // this needs to be spawned here to act as // the target for this elements 'contents' _body = spawn('div.section-body'); - + _inner.push(_body); - + if (opts.footer) { - _inner.push(['footer.section-footer'], opts.footer); + _inner.push(['footer.section-footer'], opts.footer); } - + _section = spawn('div.panel-section', opts.element, _inner); - + return { target: _body, element: _section, @@ -404,9 +471,9 @@ var XNAT = getObject(XNAT || {}); panel.select = {}; panel.select.menu = function panelSelectSingle(opts, multi){ - + var _menu; - + opts = getObject(opts); opts.element = opts.element || opts.config || {}; opts.element.name = opts.element.name || opts.name || ''; @@ -435,12 +502,12 @@ var XNAT = getObject(XNAT || {}); panel.select.multi = function panelSelectMulti(opts){ return panel.select.menu(opts, true) }; - + panel.selectMenu = function panelSelectMenu(opts){ opts = getObject(opts); return XNAT.ui.template.panelSelect(opts).spawned; }; - + function footerButton(text, type, disabled, classes){ var button = { diff --git a/src/main/webapp/scripts/xnat/ui/templates.js b/src/main/webapp/scripts/xnat/ui/templates.js index 36c847f7d862b5efa7d0abcb3847d6229602e396..c1aa97c31162fa813952f0b5b569feff88ead35b 100644 --- a/src/main/webapp/scripts/xnat/ui/templates.js +++ b/src/main/webapp/scripts/xnat/ui/templates.js @@ -141,6 +141,32 @@ var XNAT = getObject(XNAT); if (/checkbox|radio/i.test(opts.type||'') && opts.checked) { element.checked = true; } + + var dataGetParts; + + // set the values of form elements + if (opts.data) { + if (opts.data.get){ + dataGetParts = opts.data.get.split('|'); + $.ajax({ + method: dataGetParts[0] || 'GET', + url: XNAT.url.restUrl(dataGetParts[1] || ''), + success: function(data){ + // split object path + if (dataGetParts[2]) { + dataGetParts[2].split('.').forEach(function(part){ + data = data[part] + }); + } + // element.value = data; + // changeVal() changes the value and triggers + // the 'onchange' event + $(element).changeVal(data).dataAttr('value', data); + } + }) + } + } + return template.panelElement(opts, [ ['label.element-label|for='+element.id||opts.id, opts.label], ['div.element-wrapper', [ @@ -193,7 +219,54 @@ var XNAT = getObject(XNAT); ['div.element-wrapper', elements] ]); }; - + + + template.codeEditor = function(opts, contents){ + // options for the 'div.editor-content' element + opts = extend(true, opts, { + style: { + width: '100%', height: '100%', + position: 'absolute', + top: 0, right: 0, + bottom: 0, left: 0, + border: '1px solid #ccc' + } + }); + // don't pass 'before' and 'after' into the editor + var before = opts.before || ''; + var after = opts.after || ''; + delete opts.before; + delete opts.after; + var content = spawn('div.editor-content', opts, contents||''); + var _tmpl = ['form.code-editor', [ + before, + ['div.editor-wrapper', { + style: { + width: opts.width || '840px', + height: opts.height || '482px', + position: 'relative' + } + }, [content]], + after + ]]; + var _spawned = spawn.apply(null, _tmpl); + var _html = _spawned.outerHTML; + return { + template: _tmpl, // the raw template (Spawn array) + spawned: _spawned, // pre-spawned + editor: content, // easy-to-remember name for the editor div + target: content, // for inserting content dynamically + inner: content, + html: _html, // pre-spawned HTML + outerHTML: _html, + get: function(){ + return _spawned; + }, + getHTML: function(){ // call to get the HTML + return _html; + } + } + }; return XNAT.ui.templates = XNAT.ui.template = template;