Changeset 1159


Ignore:
Timestamp:
Nov 17, 2010, 4:20:33 PM (6 years ago)
Author:
robert@…
Message:

Improved the template editor so that template fields can be removed from templates, even if the templates are in use, but only if the template fields are never filled. (see ticket #74)

Also changed the user registration so that the administrator confirmation mails will be sent to the administrators in production environment, but still to gscfproject@… in other environments.

Location:
trunk/grails-app
Files:
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/grails-app/controllers/dbnp/authentication/UserRegistrationController.groovy

    r1147 r1159  
    1515package dbnp.authentication
    1616import grails.plugins.springsecurity.Secured
     17import org.codehaus.groovy.grails.commons.GrailsApplication
     18import grails.util.GrailsUtil
    1719
    1820class UserRegistrationController {
     
    125127        def adminLink = createLink( controller: 'userRegistration', action: 'confirmAdmin', params: [code: adminCode.token], absolute: true )
    126128
     129                // If we are in production, send the mails to all administrators
     130                // Otherwise, send it to a default (spam) mail address
     131                def adminMail = "gscfproject@gmail.com";
     132                if ( GrailsUtil.getEnvironment().equals(GrailsApplication.ENV_PRODUCTION) ) {
     133                        def administrators = SecRole.findUsers( 'ROLE_ADMIN' );
     134                        if( administrators.size() > 0 ) {
     135                                adminMail = administrators.email.toArray();
     136                        }
     137                }
     138
    127139        // Send an email to the administrators
    128140        try {
    129141                        // Determine administrator email addresses
    130142            sendMail {
    131                 to      "gscfproject@gmail.com"
     143                to      adminMail
    132144                subject "New user (" + user.username + ") at GSCF"
    133145                html    g.render(template:"/email/registrationConfirmationAdmin", model:[username: user.username, email: user.email, link: adminLink])
  • trunk/grails-app/controllers/dbnp/studycapturing/TemplateEditorController.groovy

    r1077 r1159  
    494494                templateField.properties = params
    495495        if (!templateField.hasErrors() && templateField.save(flush: true)) {
    496                         def html = g.render( template: 'elements/available', model: [templateField: templateField, ontologies: Ontology.list(), fieldTypes: TemplateFieldType.list()] );
     496
     497                        // Select the template to use for the HTML output
     498                        def renderTemplate = 'elements/available';
     499                        if( params.renderTemplate == 'selected' ) {
     500                                renderTemplate = 'elements/selected';
     501                        }
     502
     503                        // Selected fields should have a template given
     504                        def template = null;
     505                        if( params.templateId )
     506                                template = Template.findById( params.templateId );
     507                       
     508                        def html = g.render( template: renderTemplate, model: [template: template, templateField: templateField, ontologies: Ontology.list(), fieldTypes: TemplateFieldType.list()] );
    497509                        def output = [ id: templateField.id, html: html ];
    498510                        render output as JSON;
     
    635647
    636648                // If the template is in use, field can not be removed
    637                 if( template.inUse() ) {
    638                         response.status = 500;
    639                         render 'No fields can be removed from templates that are in use.'
     649                if( templateField.isFilledInTemplate(template) ) {
     650                        response.status = 500;
     651                        render 'Fields can not be removed from a template if it has been filled somewhere.'
    640652                        return;
    641653                }
  • trunk/grails-app/domain/dbnp/authentication/SecRole.groovy

    r976 r1159  
    1212                authority blank: false, unique: true
    1313        }
     14
     15        static List<SecUser> findUsers(String authority) {
     16                def userRoles = SecUserSecRole.findAllBySecRole( SecRole.findByAuthority( authority ) );
     17               
     18                def users = [];
     19                userRoles.each { users.add( it.secUser ) }
     20               
     21                return users
     22        }
    1423}
  • trunk/grails-app/domain/dbnp/studycapturing/TemplateField.groovy

    r959 r1159  
    118118
    119119        /**
    120          * The number of templates that use this template
    121          *
    122          * @returns             the number of templates that use this template.
     120         * The number of templates that use this template field
     121         *
     122         * @returns             the number of templates that use this template field.
    123123         */
    124124        def numUses() {
     125                return getUses().size();
     126        }
     127
     128        /**
     129         * Retrieves the templates that use this template field
     130         *
     131         * @returns             a list of templates that use this template field.
     132         */
     133        def getUses() {
    125134                def templates = Template.findAll();
    126135                def elements;
     136
    127137                if( templates && templates.size() > 0 ) {
    128138                        elements = templates.findAll { template -> template.fields.contains( this ) };
    129139                } else {
    130                         return 0;
     140                        return [];
    131141                }
    132142
    133                 return elements.size();
    134         }
     143                return elements;
     144        }
     145
     146        /**
     147         * Checks whether this template field is used in a template and also filled in any instance of that template
     148         *
     149         * @returns             true iff this template field is used in a template, the template is instantiated
     150         *                              and an instance has a value for this field. false otherwise
     151         */
     152        def isFilled() {
     153                // Find all entities that use this template
     154                def templates = getUses();
     155
     156                if( templates.size() == 0 )
     157                        return false;
     158
     159                def c = this.entity.createCriteria()
     160                def entities = c {
     161                        'in'("template",templates)
     162                }
     163
     164                def filledEntities = entities.findAll { entity -> entity.getFieldValue( this.name ) }
     165
     166                return filledEntities.size() > 0;
     167        }
     168
     169        /**
     170         * Checks whether this template field is used in the given template and also filled in an instance of that template
     171         *
     172         * @returns             true iff this template field is used in the given template, the template is instantiated
     173         *                              and an instance has a value for this field. false otherwise
     174         */
     175        def isFilledInTemplate(Template t) {
     176                println( "Checking field " + this.name )
     177                println( "Filled in template: " + t)
     178                if( t == null )
     179                        return false;
     180                       
     181                // If the template is not used, if can never be filled
     182                if( !t.fields.contains( this ) )
     183                        return false;
     184
     185                // Find all entities that use this template
     186                def entities = entity.findAllByTemplate( t );
     187
     188                println( "Num entities: " + entities.size() )
     189
     190                def filledEntities = entities.findAll { entity -> entity.getFieldValue( this.name ) }
     191
     192                println( "Num filled entities: " + filledEntities.size() )
     193                println( "Values: " + filledEntities*.getFieldValue( this.name ).join( ', ' ) )
     194                return filledEntities.size() > 0;
     195        }
     196
     197        /**
     198         * Check whether a templatefield that is used in a template may still be edited or deleted.
     199         * That is possible if the templatefield is never filled and the template is only used in one template
     200         *
     201         * This method should only be used for templatefields used in a template that is currently shown. Otherwise
     202         * the user may edit this template field, while it is also in use in another template than is currently shown.
     203         * That lead to confusion.
     204         *
     205         * @returns true iff this template may still be edited or deleted.
     206         */
     207        def isEditable() {
     208                return !isFilled() && numUses() == 1;
     209        }
     210
     211        /**
     212         * Checks whether the given list item is selected in an entity where this template field is used
     213         *
     214         * @param       item    ListItem to check.
     215         * @returns                     true iff the list item is part of this template field and the given list
     216         *                                      item is selected in an entity where this template field is used. false otherwise
     217         *                                      Returns false if the type of this template field is other than STRINGLIST
     218         */
     219        def entryUsed(TemplateFieldListItem item) {
     220                //return numUses() > 0;
     221        }
     222
     223        /**
     224         * Checks whether a term from the given ontology is selected in an entity where this template field is used
     225         *
     226         * @param       item    ListItem to check.
     227         * @returns                     true iff the ontology is part of this template field and a term from the given
     228         *                                      ontology is selected in an entity where this template field is used. false otherwise
     229         *                                      Returns false if the type of this template field is other than ONTOLOGY
     230         */
     231        def entryUsed(Ontology item) {
     232                //return numUses() > 0;
     233        }
     234
    135235}
  • trunk/grails-app/views/templateEditor/_ontologyDialog.gsp

    r959 r1159  
    44        Search by ncboID. Fill in the ncboID of the ontology you want to add.<br />
    55        <input class="text" type="text" name="ncboID" id="ncboIDText" onClick="$('#searchType_ncbo').attr( 'checked', true ); $( '#termID' ).val( '' );">
    6         <img id="ncbo_spinner" src="${createLinkTo( dir: 'images', file: 'spinner.gif' )}" style="margin-left: 5px; display: none;">
     6        <img id="ncbo_spinner" src="${resource( dir: 'images', file: 'spinner.gif' )}" style="margin-left: 5px; display: none;">
    77  </li>
    88  <li onClick="$('#searchType_term').attr( 'checked', true ); $( '#ncboIDText' ).val( '' );">
     
    1111        be added to the system.<br />
    1212        <g:textField class="text" name="termID" rel="ontology-all" onClick="\$('#searchType_term').attr( 'checked', true ); \$( '#ncboIDText' ).val( '' );"/>
    13         <img id="term_spinner" src="${createLinkTo( dir: 'images', file: 'spinner.gif' )}" style="margin-left: 5px; display: none;">
     13        <img id="term_spinner" src="${resource( dir: 'images', file: 'spinner.gif' )}" style="margin-left: 5px; display: none;">
    1414  </li>
    1515</ul>
  • trunk/grails-app/views/templateEditor/elements/_liFieldInUse.gsp

    r980 r1159  
    11<g:set var="numUses" value="${templateField.numUses()}" />
    22<span class="listButtons">
    3   <img onClick="showTemplateFieldForm( 'templateField_' + ${templateField.id}); this.blur(); return false;" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template field properties" title="Edit template field properties">
    4   <img class="disabled" src="${createLinkTo( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Deleting this field is not possible. Field is used in ${numUses} templates." title="Deleting this field is not possible. Field is used in ${numUses} templates.">
    5   <img onClick="addTemplateField( ${templateField.id}, null, true );" src="${createLinkTo( dir: 'images/icons', file: 'add.png', plugin: 'famfamfam' )}" alt="Add field to template" title="Add field to template">
     3  <img onClick="showTemplateFieldForm( 'templateField_' + ${templateField.id}); this.blur(); return false;" src="${resource( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template field properties" title="Edit template field properties">
     4  <img class="disabled" src="${resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Deleting this field is not possible. Field is used in ${numUses} templates." title="Deleting this field is not possible. Field is used in ${numUses} templates.">
     5  <img onClick="addTemplateField( ${templateField.id}, null, true );" src="${resource( dir: 'images/icons', file: 'add.png', plugin: 'famfamfam' )}" alt="Add field to template" title="Add field to template">
    66</span>
    77
  • trunk/grails-app/views/templateEditor/elements/_liFieldNotInUse.gsp

    r980 r1159  
    11<span class="listButtons">
    2   <img onClick="showTemplateFieldForm( 'templateField_' + ${templateField.id}); this.blur(); return false;" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template field properties" title="Edit template field properties">
    3   <img onClick="if( confirm( 'Are you sure?' ) ) { deleteTemplateField( ${templateField.id} ); }" src="${createLinkTo( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Delete this template field" title="Delete this template field">
    4   <img onClick="addTemplateField( ${templateField.id}, null, true );" src="${createLinkTo( dir: 'images/icons', file: 'add.png', plugin: 'famfamfam' )}" alt="Add field to template" title="Add field to template">
     2  <img onClick="showTemplateFieldForm( 'templateField_' + ${templateField.id}); this.blur(); return false;" src="${resource( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template field properties" title="Edit template field properties">
     3  <img onClick="if( confirm( 'Are you sure?' ) ) { deleteTemplateField( ${templateField.id} ); }" src="${resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Delete this template field" title="Delete this template field">
     4  <img onClick="addTemplateField( ${templateField.id}, null, true );" src="${resource( dir: 'images/icons', file: 'add.png', plugin: 'famfamfam' )}" alt="Add field to template" title="Add field to template">
    55</span>
    66
  • trunk/grails-app/views/templateEditor/elements/_liFieldSelected.gsp

    r1136 r1159  
    11<span class="listButtons">
    2   <img onClick="showTemplateFieldForm( 'templateField_' + ${templateField.id}); this.blur(); return false;" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Show template field properties" title="Show template field properties">
    3 
    4   <g:if test="${template.inUse()}">
    5         <img class="disabled" src="${createLinkTo( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="This field can not be removed from the template, as the template is still in use." title="This field can not be removed from the template, as the template is still in use.">
     2  <img onClick="showTemplateFieldForm( 'templateField_' + ${templateField.id}); this.blur(); return false;" src="${resource( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Show template field properties" title="Show template field properties">
     3  <g:if test="${templateField.isFilledInTemplate(template)}">
     4        <img class="disabled" src="${resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="This field can not be removed from the template, as this field is already in use." title="This field can not be removed from the template, as this field is already in use.">
    65  </g:if>
    76  <g:else>
    8         <img onClick="removeTemplateField( ${templateField.id} ); moveFieldListItem( ${templateField.id}, '#availableTemplateFields' );" src="${createLinkTo( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Remove this template field from the template" title="Remove this template field from the template">
     7        <img onClick="removeTemplateField( ${templateField.id} ); moveFieldListItem( ${templateField.id}, '#availableTemplateFields' );" src="${resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Remove this template field from the template" title="Remove this template field from the template">
    98  </g:else>
    109</span>
     
    1413  (<g:if test="${templateField.unit}">${templateField.unit}, </g:if><g:render template="elements/${templateField.type.toString().toLowerCase().replaceAll(/ /,'_')}" model="[templateField: templateField]"/>)
    1514
    16   <form class="templateField_form" id="templateField_${templateField.id}_form">
    17           <g:render template="elements/disabledFieldForm" model="['templateField': templateField, 'ontologies': ontologies, 'fieldTypes': fieldTypes]"/>
    18           <div class="templateFieldButtons">
    19                   <input type="button" value="Close" onClick="hideTemplateFieldForm( ${templateField.id} );">
    20           </div>
     15  <form class="templateField_form" id="templateField_${templateField.id}_form" action="updateField">
     16          <g:if test="${templateField.isEditable()}">
     17                <g:hiddenField name="id" value="${templateField.id}" />
     18                <g:hiddenField name="version" value="${templateField.version}" />
     19                <g:hiddenField name="renderTemplate" value="selected" />
     20                <g:hiddenField name="templateId" value="${template.id}" />
     21                <g:render template="elements/fieldForm" model="['templateField': templateField, 'ontologies': ontologies, 'fieldTypes': fieldTypes]"/>
     22                <div class="templateFieldButtons">
     23                        <input type="button" value="Save" onClick="updateTemplateField( ${templateField.id} );">
     24                        <input type="button" value="Close" onClick="hideTemplateFieldForm( ${templateField.id} );">
     25                </div>
     26          </g:if>
     27        <g:else>
     28                <g:render template="elements/disabledFieldForm" model="['templateField': templateField, 'ontologies': ontologies, 'fieldTypes': fieldTypes]"/>
     29                <div class="templateFieldButtons">
     30                        <input type="button" value="Close" onClick="hideTemplateFieldForm( ${templateField.id} );">
     31                </div>
     32        </g:else>
    2133  </form>
  • trunk/grails-app/views/templateEditor/elements/_liTemplateEditable.gsp

    r1027 r1159  
    11<span class="listButtons">
    2   <img onClick="editTemplate( ${template.id} );" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template properties" title="Edit template properties">
    3   <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">
    5   <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">
     2  <img onClick="editTemplate( ${template.id} );" src="${resource( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template properties" title="Edit template properties">
     3  <img onClick="editFields( ${template.id} );"src="${resource( 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="${resource( dir: 'images/icons', file: 'page_copy.png', plugin: 'famfamfam' )}" alt="Clone this template" title="Clone this template">
     5  <img onClick="if( confirm( 'Are you sure?' ) ) { deleteTemplate( ${template.id} ); }" src="${resource( dir: 'images/icons', file: 'delete.png', plugin: 'famfamfam' )}" alt="Delete this template" title="Delete this template">
    66</span>
    77${template.name}
  • trunk/grails-app/views/templateEditor/elements/_liTemplateNonEditable.gsp

    r1027 r1159  
    11<g:set var="numUses" value="${template.numUses()}" />
    22<span class="listButtons">
    3   <img onClick="editTemplate( ${template.id} );" src="${createLinkTo( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template properties" title="Edit template properties">
    4   <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">
    6   <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.">
     3  <img onClick="editTemplate( ${template.id} );" src="${resource( dir: 'images/icons', file: 'application_edit.png', plugin: 'famfamfam' )}" alt="Edit template properties" title="Edit template properties">
     4  <img onClick="editFields( ${template.id} );"src="${resource( 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="${resource( dir: 'images/icons', file: 'page_copy.png', plugin: 'famfamfam' )}" alt="Clone this template" title="Clone this template">
     6  <img class="disabled" src="${resource( 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.">
    77</span>
    88${template.name}
  • trunk/grails-app/views/templateEditor/elements/_selected.gsp

    r959 r1159  
    11<li class="ui-state-default  <g:if test="${templateField.required}">required</g:if>" id="templateField_${templateField.id}">
    2     <g:render template="elements/liFieldSelected" model="['templateField': templateField, 'template': template, 'fieldTypes': fieldTypes]"/>
     2  <g:render template="elements/liFieldSelected" model="['templateField': templateField, 'template': template, 'ontologies': ontologies, 'fieldTypes': fieldTypes]"/>
    33</li>
  • trunk/grails-app/views/templateEditor/index.gsp

    r1125 r1159  
    1919                <meta name="layout" content="${layout}"/>
    2020                <title>template editor</title>
    21                 <script src="${createLinkTo(dir: 'js', file: 'templateEditor.js')}" type="text/javascript"></script>
    22                 <link rel="stylesheet" href="${createLinkTo(dir: 'css', file: 'templateEditor.css')}" />
     21                <script src="${resource(dir: 'js', file: 'templateEditor.js')}" type="text/javascript"></script>
     22                <link rel="stylesheet" href="${resource(dir: 'css', file: 'templateEditor.css')}" />
    2323                <style type="text/css">
    2424                  #content .templateEditorStep { font-size: 0.8em; }
  • trunk/grails-app/views/user/edit.gsp

    r1152 r1159  
    2424                        </p>
    2525          </div>
     26        </g:if>
    2627        <h3><g:message code="default.edit.label" args="[entityName]"/></h3>
    2728
     
    5657                <div>
    5758                        <g:checkBox name="${entry.key.authority}" value="${entry.value}"/>
    58                         <g:link controller='role' action='edit' id='${entry.key.id}'>${entry.key.authority.encodeAsHTML()}</g:link>
     59                        ${entry.key.authority.encodeAsHTML()}
    5960                </div>
    6061                </g:each>
Note: See TracChangeset for help on using the changeset viewer.