Changeset 996


Ignore:
Timestamp:
Oct 26, 2010, 3:19:22 PM (10 years ago)
Author:
robert@…
Message:

Implemented clone feature in template editor (ticket #6), added a rest call 'getUser' and added webflow to the application.properties again.

Location:
trunk
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/application.properties

    r995 r996  
    11#Grails Metadata file
    2 #Mon Oct 25 15:43:32 CEST 2010
     2#Tue Oct 26 15:12:32 CEST 2010
    33app.grails.version=1.3.5
    44app.name=gscf
     
    1111plugins.hibernate=1.3.5
    1212plugins.jquery=1.4.3.2
     13plugins.jumpbar=0.1
    1314plugins.mail=0.9
    1415plugins.oauth=0.10
     
    1617plugins.spring-security-core=1.0.1
    1718plugins.tomcat=1.3.5
    18 plugins.jumpbar=0.1
     19plugins.webflow=1.3.4
  • trunk/grails-app/controllers/RestController.groovy

    r983 r996  
    6767        }
    6868
     69        /**
     70         * REST resource for data modules.
     71         * Consumer and token should be supplied via URL parameters.
     72         * Provides the details of the user that has logged in
     73         *
     74         * @param       consumer        consumer name of the calling module
     75         * @param       token           token for the authenticated user (e.g. session_id)
     76         * @return bool {"username": "...", "id": ... } when user/password is logged in.
     77         */
     78        def getUser = {
     79                SecUser user = AuthenticationService.getRemotelyLoggedInUser( params.consumer, params.token )
     80                def reply = [username: user.username, id: user.id]
     81                render reply as JSON
     82        }
    6983
    7084        /**
  • trunk/grails-app/controllers/dbnp/authentication/UserController.groovy

    r985 r996  
    1616
    1717import grails.converters.JSON
    18 
     18import grails.plugins.springsecurity.Secured
    1919import org.springframework.dao.DataIntegrityViolationException
    2020
     
    2222 * @author <a href='mailto:burt@burtbeckwith.com'>Burt Beckwith</a>
    2323 */
     24@Secured(['ROLE_ADMIN'])
    2425class UserController {
    2526
     
    213214
    214215        protected findById() {
     216                if(!params.id) {
     217                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
     218                        redirect action: search
     219                }
     220
    215221                def user = SecUser.get(params.id)
     222               
    216223                if (!user) {
    217224                        flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'user.label', default: 'User'), params.id])}"
  • trunk/grails-app/controllers/dbnp/studycapturing/TemplateEditorController.groovy

    r959 r996  
    1616import dbnp.data.*
    1717import dbnp.studycapturing.*
     18import dbnp.authentication.AuthenticationService
    1819import cr.co.arquetipos.crypto.Blowfish
    1920import grails.converters.*
     
    2324    def entityName;
    2425    def entity;
    25  
     26
     27        def AuthenticationService
     28       
    2629        /**
    2730    * Study template editor page
     
    174177         *                                      On error the method gives a HTTP response status 500 and the error
    175178     */
    176     def createTemplate = {
     179   def createTemplate = {
    177180                // Decode the entity
    178181        if( !_checkEntity() ) {
     
    194197            response.status = 500;
    195198            render 'Template could not be created because errors occurred.';
     199            return
     200        }
     201    }
     202
     203    /**
     204     * Clones a template using a AJAX call
     205         *
     206         * @return                      JSON object with two entries:
     207         *                                              id: [id of this object]
     208         *                                              html: HTML of the contents of the LI-item that will be added.
     209         *                                      On error the method gives a HTTP response status 500 and the error
     210     */
     211     def cloneTemplate = {
     212        // Search for the template field
     213        def template = Template.get( params.id );
     214        if( !template ) {
     215            response.status = 404;
     216            render 'Template not found';
     217            return;
     218        }
     219
     220                // Create the template fields and add it to the template
     221                def newTemplate = new Template( template, authenticationService.getLoggedInUser() );
     222        if (newTemplate.validate() && newTemplate.save(flush: true)) {
     223                        def html = g.render( template: 'elements/liTemplate', model: [template: newTemplate] );
     224                        def output = [ id: newTemplate.id, html: html ];
     225                        render output as JSON;
     226        } else {
     227            response.status = 500;
     228            render 'Template could not be cloned because errors occurred.';
    196229            return
    197230        }
     
    607640        def currentIndex = template.fields.indexOf( templateField );
    608641        def moveField = template.fields.remove( currentIndex );
     642
     643                println( "Old: " + currentIndex + " - New: " + params.position );
     644               
    609645        template.fields.add( Integer.parseInt( params.position ), moveField );
    610646                template.save(flush:true);
  • trunk/grails-app/controllers/dbnp/studycapturing/WizardController.groovy

    r978 r996  
    2929@Secured(['IS_AUTHENTICATED_REMEMBERED'])
    3030class WizardController {
    31         def AuthenticationService
     31        def AuthenticationService
    3232
    3333        /**
  • trunk/grails-app/domain/dbnp/studycapturing/Study.groovy

    r976 r996  
    2929        List assays
    3030        boolean published = false // Determines whether a study is private (only accessable by the owner and writers) or published (also visible to readers)
    31         boolean publicstudy = false  // Determines whether anonymous users are allowed to see this study. This has only effect when published = true
     31    boolean publicstudy = false  // Determines whether anonymous users are allowed to see this study. This has only effect when published = true
    3232       
    3333        static hasMany = [             
  • trunk/grails-app/domain/dbnp/studycapturing/Template.groovy

    r976 r996  
    22
    33import dbnp.authentication.SecUser
     4import dbnp.authentication.AuthenticationService
    45
    56/**
     
    3738
    3839        static hasMany = [fields: TemplateField]
    39 
    4040        static mapping = {
    4141        }
     
    7777                // name(unique:['entity'])
    7878
     79        }
     80
     81        public Template() {
     82                super()
     83        }
     84
     85        /**
     86         * Creates a clone of the given other template and also copies its owner
     87         *
     88         * @param       otherTemplate
     89         */
     90        public Template( Template otherTemplate) {
     91                this()
     92
     93                //authenticationService = new AuthenticationService()
     94
     95                this.name = otherTemplate.name + " (Copy)"
     96                this.description = otherTemplate.description
     97                this.entity = otherTemplate.entity
     98                this.owner = otherTemplate.owner
     99
     100                // The fields are copied by reference
     101                this.fields = otherTemplate.fields
     102        }
     103
     104        /**
     105         * Creates a clone of the given other template. The currently logged in user
     106         * is set as the owner
     107         * @param       otherTemplate
     108         */
     109        public Template( Template otherTemplate, SecUser owner ) {
     110                this()
     111
     112                //authenticationService = new AuthenticationService()
     113
     114                this.name = otherTemplate.name + " (Copy)"
     115                this.description = otherTemplate.description
     116                this.entity = otherTemplate.entity
     117                this.owner = owner
     118
     119                // The fields are copied by reference
     120                this.fields = []
     121                otherTemplate.fields.each {
     122                        this.fields.add( it )
     123                }
    79124        }
    80125
  • trunk/grails-app/views/templateEditor/elements/_liTemplateEditable.gsp

    r980 r996  
    22  <img onClick="editTemplate( ${template.id} );" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template properties" title="Edit template properties">
    33  <img onClick="editFields( ${template.id} );"src="${createLinkTo( dir: 'images/icons', file: 'application_form.png', plugin: 'famfamfam' )}" alt="Add/remove template fields" title="Add/remove template fields">
     4  <img onClick="cloneTemplate( ${template.id} );"src="${createLinkTo( dir: 'images/icons', file: 'page_copy.png', plugin: 'famfamfam' )}" alt="Clone this template" title="Clone this template">
    45  <img onClick="if( confirm( 'Are you sure?' ) ) { deleteTemplate( ${template.id} ); }" src="${createLinkTo( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Delete this template" title="Delete this template">
    56</span>
  • trunk/grails-app/views/templateEditor/elements/_liTemplateNonEditable.gsp

    r980 r996  
    33  <img onClick="editTemplate( ${template.id} );" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template properties" title="Edit template properties">
    44  <img onClick="editFields( ${template.id} );"src="${createLinkTo( dir: 'images/icons', file: 'application_form.png', plugin: 'famfamfam' )}" alt="Add/remove template fields" title="Add/remove template fields">
     5  <img onClick="cloneTemplate( ${template.id} );"src="${createLinkTo( dir: 'images/icons', file: 'page_copy.png', plugin: 'famfamfam' )}" alt="Clone this template" title="Clone this template">
    56  <img class="disabled" src="${createLinkTo( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Deleting this template is not possible. Template is used in ${numUses} objects." title="Deleting this template is not possible. Template is used in ${numUses} objects.">
    67</span>
  • trunk/grails-app/views/templateEditor/index.gsp

    r959 r996  
    5959                </div>
    6060
     61                <div id="wait" class="wait">
     62                  &nbsp;
     63                </div>
     64                <div class="wait_text wait">
     65                  <img src="<g:resource dir="images" file="spinner.gif" />"> Please wait
     66                </div>
     67
     68
    6169        </body>
    6270</html>
  • trunk/grails-app/views/templateEditor/template.gsp

    r959 r996  
    8888                                <ol id="selectedTemplateFields" class="templateFields <g:if test="${template.inUse()}">inUse</g:if>">
    8989                                        <g:render template="elements/selected" var="templateField" collection="${template.fields}" model="['template':template]"/>
     90                                        <% /* NB: this empty field should always be the last in the list! */ %>
    9091                                        <li class="empty ui-state-default" <g:if test="${template.fields?.size() > 0 }">style='display: none;'</g:if>>This template does not yet contain any fields. Drag a field to this list or use the 'Add field button'.</li>
    9192                                </ol>
     
    9697                                <p>These fields are available for adding to the template. Drag a field to the template to add it.</p>
    9798                                <ol id="availableTemplateFields" class="templateFields">
     99                                        <g:render template="elements/available" var="templateField" collection="${allFields - template.fields}" />
    98100                                        <li class="empty ui-state-default" <g:if test="${allFields.size() > template.fields.size()}">style='display: none;'</g:if>>There are no additional fields that can be added. Use the 'Create new field' button to create new fields.</li>
    99                                         <g:render template="elements/available" var="templateField" collection="${allFields - template.fields}" />
    100101                                </ol>
    101102
     
    121122                </div>
    122123
    123         </body>
     124                <div id="wait" class="wait">
     125                  &nbsp;
     126                </div>
     127                <div class="wait_text wait">
     128                  <img src="<g:resource dir="images" file="spinner.gif" />"> Please wait
     129                </div>
     130                </body>
    124131</html>
  • trunk/grails-app/views/user/create.gsp

    r985 r996  
    1010      });
    1111    </script>
     12        <style type="text/css">
     13          div.usermanagement { font-size: 0.8em; }
     14        </style>
    1215</head>
    1316
     
    1821<g:form action="save" name='userCreateForm' class="button-style">
    1922
    20       <div id="tabs">
     23      <div id="tabs" class="usermanagement">
    2124        <ul>
    2225          <li><a href="#userinfo">User info</a></li>
     
    5457  <input type="submit" value="Save" />
    5558
    56   <g:if test='${user}'>
    57         DELETE
    58   </g:if>
    59 
    6059</div>
    6160
    6261</g:form>
    63 
    64 <g:if test='${user}'>
    65   deleteform
    66 </g:if>
    6762
    6863<script>
  • trunk/grails-app/views/user/edit.gsp

    r985 r996  
    1010      });
    1111    </script>
     12        <style type="text/css">
     13          div.usermanagement { font-size: 0.8em; }
     14        </style>
    1215</head>
    1316
     
    2023<g:hiddenField name="version" value="${user?.version}"/>
    2124
    22       <div id="tabs">
     25      <div id="tabs" class="usermanagement">
    2326        <ul>
    2427          <li><a href="#userinfo">User info</a></li>
     
    5760
    5861  <g:if test='${user}'>
    59         DELETE
     62    <input type="button" value="Delete" onClick="$('#userDeleteForm').submit(); return false;"/>
    6063  </g:if>
    6164
     
    6568
    6669<g:if test='${user}'>
    67   deleteform
     70  <g:form action="delete" name='userDeleteForm'>
     71        <g:hiddenField name="id" value="${user?.id}"/>
     72  </g:form>
    6873</g:if>
    6974
  • trunk/grails-app/views/user/search.gsp

    r985 r996  
    1010        <g:form action='userSearch' name='userSearchForm'>
    1111
     12                <g:if test="${flash.message}">
     13                  <p>
     14                        ${flash.message}
     15                  </p>
     16                </g:if>
    1217                <br/>
    1318
  • trunk/web-app/css/templateEditor.css

    r959 r996  
    8282}
    8383
     84/* Please wait dialog */
     85#wait { /* Transparency, see http://hungred.com/how-to/css-opacity-cross-browser-compatible/ */
     86        filter: alpha(opacity:0.5);
     87        KHTMLOpacity: 0.5;
     88        MozOpacity: 0.5;
     89        -khtml-opacity:.50;
     90        -ms-filter:”alpha(opacity=50)”;
     91        -moz-opacity:.50;
     92        filter:alpha(opacity=50);
     93        opacity:.50;
     94}
     95#wait { position: absolute; left: 0; top: 0; width: 100%; height: 100%; z-index: 100;  background-color: #f2f5f7; }
     96.wait_text { position: absolute; left: 50%; top: 50%; margin-left: -100px; margin-top: -20px; width: 200px; height: 40px; text-align: center; font-weight: bold; background-color: white; border: 1px solid #006DBA; padding-top: 13px; vertical-align: center; }
     97.wait { display: none; }
     98
    8499/* Add Ontology dialog */
    85100#addOntology { list-style-type: none; padding-left: 0; }
  • trunk/web-app/js/templateEditor.js

    r959 r996  
    6161    var formEl = $( '#template_' + id + '_form' );
    6262
     63        showWaiting();
     64
    6365    // Update the field
    6466    $.ajax({
     
    7375        error:      function( request ) {
    7476            alert( "Could not create template: " + request.responseText );
    75         }
     77        },
     78                complete: function( request, textStatus ) {
     79                        hideWaiting();
     80                }
    7681    });
    7782}
     
    8287function updateTemplate( id ) {
    8388    var formEl = $( '#template_' + id + '_form' );
     89
     90        showWaiting();
    8491
    8592    // Update the field
     
    95102        error:      function( request ) {
    96103            alert( "Could not update template: " + request.responseText );
    97         }
     104        },
     105                complete: function( request, textStatus ) {
     106                        hideWaiting();
     107                }
    98108    });
    99109}
     
    103113 */
    104114function deleteTemplate( id ) {
    105     // Update the field
     115
     116        showWaiting();
     117
     118        // Update the field
    106119    $.ajax({
    107120        url:        baseUrl + '/templateEditor/deleteTemplate',
     
    116129        error:      function( request ) {
    117130            alert( "Could not delete template: " + request.responseText );
    118         }
     131        },
     132                complete: function( request, textStatus ) {
     133                        hideWaiting();
     134                }
    119135    });
    120136
    121137        return true;
     138}
     139
     140/**
     141 * Clones a template using AJAX
     142 */
     143function cloneTemplate( id ) {
     144        showWaiting();
     145
     146    // Update the field
     147    $.ajax({
     148        url:        baseUrl + '/templateEditor/cloneTemplate/' + id,
     149                dataType:   'json',
     150        type:       "POST",
     151        success:    function(data, textStatus, request) {
     152            addTemplateListItem( data.id, data.html );
     153        },
     154        error:      function( request ) {
     155            alert( "Could not clone template: " + request.responseText );
     156        },
     157                complete: function( request, textStatus ) {
     158                        hideWaiting();
     159                }
     160    });
    122161}
    123162
     
    203242        var templateId = $('#templateSelect').val();
    204243
     244        showWaiting();
     245
    205246    // Update the field
    206247    $.ajax({
     
    215256        error:       function( request ) {
    216257            alert( "Could not add template field: " + request.responseText );
    217         }
     258        },
     259                complete: function( request, textStatus ) {
     260                        hideWaiting();
     261                }
    218262    });
    219263}
     
    224268function updateTemplateField( id ) {
    225269    var formEl = $( '#templateField_' + id + '_form' );
     270
     271        showWaiting();
    226272
    227273    // Update the field
     
    237283        error:      function( request ) {
    238284            alert( "Could not update template field: " + request.responseText );
    239         }
     285        },
     286                complete: function( request, textStatus ) {
     287                        hideWaiting();
     288                }
    240289    });
    241290}
     
    245294 */
    246295function deleteTemplateField( id ) {
     296        showWaiting();
     297
    247298    // Delete the field
    248299    $.ajax({
     
    258309        error:      function( request ) {
    259310            alert( "Could not delete template field: " + request.responseText );
    260         }
     311        },
     312                complete: function( request, textStatus ) {
     313                        hideWaiting();
     314                }
    261315    });
    262316
     
    266320/**
    267321 * Is triggered when an item from the templatefields has been moved and
    268  * shoule be updated
     322 * should be updated
    269323 */
    270324function updateTemplateFieldPosition( event, ui ) {
     
    279333                return true;
    280334        }
     335
    281336    // Find the new position of the element in the list
    282337    // http://stackoverflow.com/questions/2979643/jquery-ui-sortable-position
    283338    //
    284     // Because there is also a hidden 'empty template' list item in the list,
    285     // the number is decreased by 1
    286     var newposition = ui.item.index() - 1;
     339    // There is also a hidden 'empty template' list item in the list. This is
     340        // the last item in the list, so it doesn't matter in this computation
     341    var newposition = ui.item.index();
    287342
    288343    // Find the ID of the templateField and template
     
    296351    // Disable sorting until this move has been saved (in order to prevent collisions
    297352    $( '#templateFields' ).sortable( 'disable' );
     353
     354        showWaiting();
    298355
    299356    // Move the item
     
    310367                        undoMove();
    311368                        alert( "Could not move template field: " + request.responseText );
    312         }
     369        },
     370                complete: function( request, textStatus ) {
     371                        hideWaiting();
     372                }
    313373    });
    314374}
     
    345405        var templateId = $('#templateSelect').val();
    346406
     407        showWaiting();
     408
    347409    // Update the field
    348410    $.ajax({
     
    369431
    370432            alert( "Could not add template field: " + request.responseText );
    371         }
     433        },
     434                complete: function( request, textStatus ) {
     435                        hideWaiting();
     436                }
    372437    });
    373438
     
    397462        var templateId = $('#templateSelect').val();
    398463
     464        showWaiting();
     465
    399466    // Update the field
    400467    $.ajax({
     
    420487
    421488                        alert( "Could not delete template field: " + request.responseText );
    422         }
     489        },
     490                complete: function( request, textStatus ) {
     491                        hideWaiting();
     492                }
    423493    });
    424494
     
    514584        }
    515585}
     586
     587function showWaiting() { $( '.wait' ).show() }
     588function hideWaiting() { $( '.wait' ).hide() }
    516589
    517590/************************************
Note: See TracChangeset for help on using the changeset viewer.