diff --git a/backend/TE/AppDB.php b/backend/TE/AppDB.php index 6661e15f3416eba94501a83fc0b341f3e563e42b..c229911f9a35cef1db1c8997812b49788e7887f5 100644 --- a/backend/TE/AppDB.php +++ b/backend/TE/AppDB.php @@ -287,6 +287,39 @@ class AppDB_TE extends AppDB ); } + public function getExerciseAssignmentsUsers( $exid ) + { + $this->checkAdmin(); + + $sql = "SELECT person.id as uid, person.name as uname + FROM observation + JOIN object ON observation.assignment = object.id + JOIN assignment ON assignment.id = observation.assignment + JOIN person ON object.creator = person.id + WHERE assignment.exercise = " . ( int ) $exid . " + GROUP BY person.id, person.name"; + + return $this->query( $sql ); + } + + public function getPFSPUser( $exid, $uid ) + { + $this->checkAdmin(); + + $sql = "SELECT person.id as uid, person.name as uname, observation.value as pfsp + FROM observation + JOIN observationtype ON observationtype.id = observation.type + JOIN object ON observation.assignment = object.id + JOIN assignment ON assignment.id = observation.assignment + JOIN person ON object.creator = person.id + WHERE assignment.exercise = " . ( int ) $exid . " AND + person.id = " . ( int ) $uid . " AND + observationtype.name = 'mark-pfsp' + LIMIT 1"; + + return $this->query( $sql ); + } + public function getExerciseAssignments( $id, $extended = false, $anonymousreview = 0, $multiCaseViewer = NULL ) { $this->checkAdmin(); @@ -485,6 +518,20 @@ class AppDB_TE extends AppDB return $res; } + public function getPFSP( $userid, $exid ) + { + $this->checkAdmin(); + $sql = " + SELECT observation.value + FROM observation + JOIN object ON observation.assignment = object.id + JOIN assignment ON assignment.id = observation.assignment + WHERE observation.type = ( SELECT id FROM observationtype WHERE name = 'mark-pfsp' ) AND + object.creator = " . ( int ) $userid . " AND + exercise = " . ( int ) $exid . ";"; + + return $this->query( $sql ); + } public function saveExercise( $id, $name, $description, $mark, $print ) { $this->beginTransaction(); diff --git a/js/pianos4.js b/js/pianos4.js index 0dfa2f947007bc93f7ccfb7c18de988b212b367a..f93e9afcc630c545dfcb91d62b9739dfcab858fc 100644 --- a/js/pianos4.js +++ b/js/pianos4.js @@ -2320,6 +2320,12 @@ function Pianos4( params ) self.onSelectNextUserResults(); } ) ) + .append( + createBtn( 'ui-icon-note', 'PFSP', function() + { + showUserData(); + } ) + ) .append( $( '' ) .addClass( 'please_wait' ) @@ -2780,7 +2786,8 @@ function Pianos4( params ) content.data( 'pianos4', data ); onConclusionUpdated(); }, - initData + initData, + false ); } ) ) @@ -4405,7 +4412,170 @@ function Pianos4( params ) onUsersResultsToggled( me.numChecked ); } - + + var showUserData = function() + { + var complete = function( data ) + { + var dlgopts = { + autoOpen: true, + modal: false, + width: 600, + title: 'All user data', + close: function() + { + $( this ).remove(); + }, + buttons: { + 'Close': function() + { + $( this ).dialog( 'close' ); + } + }, + }; + + var div = $( '
' ); + var id_base = 'pianos4_resultdlg_opt_' + ( new Date().getTime() ); + + div.qtable( { + data: data.ret, + columnMode: 'mapping', + columns: [ + { + title: 'User', + render: function( data, i, j, cell ) + { + cell.append( + $( '' ) + .text( data[ i ].uname ) + ); + }, + }, { + title: 'PFSP', + render: function( data, i, j, cell ) + { + cell.append( + $( '' ) + .attr( 'id', 'userPFSP_' + data[ i ].uid ) + .text( 'Loading...' ) + .css( 'text-decoration', 'underline' ) + .css( 'cursor', 'pointer' ) + .bind( 'click', function(){ + showPFSPUser( params.exid, data[ i ].uid ); + } ) + ); + + self.ajax( { + pendingMessage: 'Loading conclusions', + url: '?action=rpc&method=getPFSPUser', + data: { + exid: params.exid, + uid: data[ i ].uid + }, + dataType: 'json', + success: function( d ) + { + if( ! d.error ) + { + if( d.ret.length == 0 ) + { + v = 'None'; + } else { + v = d.ret[ 0 ].pfsp; + v = v.replace( /[{}""\[\]]/g, '' ).split( "," ); + v = v.length; + + if( v == 1 ) + v = v + " zone"; + else if( v > 1 ) + v = v + " zones"; + else + v = "None"; + } + + $( '#userPFSP_' + data[ i ].uid ).text( v ); + } else { + toastr.error( "Server error" ); + $( '#userPFSP_' + data[ i ].uid ).text( 'Error' ); + } + }, + error: function() + { + toastr.error( "Network error" ); + $( '#userPFSP_' + data[ i ].uid ).text( 'Error' ); + } + } ); + + }, + } + ] + } ); + + var dlg = $( '' ) + .addClass( 'pianos4_dialog' ) + .css( 'max-height', $( window ).height() - 140 ) + .append( div ); + + self.dialog( dlg, dlgopts ); + } + + self.ajax( { + pendingMessage: 'Loading conclusions', + url: '?action=rpc&method=getExerciseAssignmentsUsers', + data: { + exid: params.exid + }, + dataType: 'json', + success: function( data ) + { + complete( data ); + }, + error: function() + { + toastr.error( "Network error" ); + } + } ); + } + + var showPFSPUser = function( exid, userid ) + { + self.ajax( { + pendingMessage: 'Loading PFSP', + url: '?action=rpc&method=getPFSP', + data: { + exid: exid, + userid: userid + }, + dataType: 'json', + success: function( data ) + { + if( ! data.error ) + { + if( data.ret.length === 0 ) + { + toastr.info( "No data" ); + } else { + var d = data.ret[ 0 ].value; + d = d.replace( /[{}""\[\]]/g, '' ).split( "," ); + showPalmFingerSegementPositionDialog( + 'Palm and finger segment positions', + Pianos4Constants.conclusions.analysis.palm_finger_segment_position, + null, + d, + true + ); + } + } else { + toastr.error( "Server error" ); + } + }, + error: function() + { + toastr.error( "Network error" ); + } + } ); + } + this.onSelectNextUserResults = function( backwards ) { var table = panes.results.find( 'table>tbody' ); @@ -5038,7 +5208,7 @@ function Pianos4( params ) self.dialog( dlg, dlgopts ); } - var showPalmFingerSegementPositionDialog = function( title, pfsp, callback, initValue ) + var showPalmFingerSegementPositionDialog = function( title, pfsp, callback, initValue, review = false ) { var div = $( '' ); var id_base = 'pianos4_pfspdlg_' + ( new Date().getTime() ); @@ -5258,77 +5428,80 @@ function Pianos4( params ) preloader = [ ...preloader, ...sz.sel ]; - map.append( - $( ' ' ) - .attr( 'shape', 'polygon' ) - .attr( 'coords', sz.coords ) - .attr( 'data-selection', sz.sel ) - .attr( 'data-desc', sz.desc ) - .attr( 'data-zone', sz.zone ) - .attr( 'data-lat', sz.lat ) - .mouseover( function() - { - $( '#pfsp_current_hover' ) - .text( $( this )[ 0 ].dataset.desc ); - - var s = $( this )[ 0 ].dataset.selection.split( ',' ); - var zone = $( this )[ 0 ].dataset.zone; - var lat = $( this )[ 0 ].dataset.lat; - - getAndUpdateSelection( s, zone, lat ); - } ) - .mouseout( function() - { - $( '#pfsp_current_hover' ) - .text( 'None' ); - - updateSelection(); - } ) - .on( 'click', function( e ) - { - e.defaultPrevented; - - var sel = $( this )[ 0 ].dataset.selection.split( ',' ); - var zone = $( this )[ 0 ].dataset.zone; - var lat = $( this )[ 0 ].dataset.lat; - var desc = $( this )[ 0 ].dataset.desc; - - var clicked = getRelatedAreas( sel, zone, lat ); - - var alreadySelected = function( a ) + if( ! review ) + { + map.append( + $( ' ' ) + .attr( 'shape', 'polygon' ) + .attr( 'coords', sz.coords ) + .attr( 'data-selection', sz.sel ) + .attr( 'data-desc', sz.desc ) + .attr( 'data-zone', sz.zone ) + .attr( 'data-lat', sz.lat ) + .mouseover( function() { - return selected_areas.indexOf( a ) > -1; - } - - if( desc == 'Left full palm' || desc == 'Left upper palm' || desc == 'Left lower palm' || - desc == 'Right full palm' || desc == 'Right upper palm' || desc == 'Right lower palm' || - desc == 'Left tips' || desc == 'Right tips' ) + $( '#pfsp_current_hover' ) + .text( $( this )[ 0 ].dataset.desc ); + + var s = $( this )[ 0 ].dataset.selection.split( ',' ); + var zone = $( this )[ 0 ].dataset.zone; + var lat = $( this )[ 0 ].dataset.lat; + + getAndUpdateSelection( s, zone, lat ); + } ) + .mouseout( function() { - if( clicked.every( alreadySelected ) ) - { - for( var i in clicked ) - selected_areas.splice( selected_areas.indexOf( clicked[ i ] ), 1 ); + $( '#pfsp_current_hover' ) + .text( 'None' ); - } else { - selected_areas = [ ...selected_areas, ...clicked ]; + updateSelection(); + } ) + .on( 'click', function( e ) + { + e.defaultPrevented; + + var sel = $( this )[ 0 ].dataset.selection.split( ',' ); + var zone = $( this )[ 0 ].dataset.zone; + var lat = $( this )[ 0 ].dataset.lat; + var desc = $( this )[ 0 ].dataset.desc; + + var clicked = getRelatedAreas( sel, zone, lat ); + + var alreadySelected = function( a ) + { + return selected_areas.indexOf( a ) > -1; } - } else { - var addToList = selected_areas.indexOf( sel[ 0 ] ) == -1; - for( var i in clicked ) + if( desc == 'Left full palm' || desc == 'Left upper palm' || desc == 'Left lower palm' || + desc == 'Right full palm' || desc == 'Right upper palm' || desc == 'Right lower palm' || + desc == 'Left tips' || desc == 'Right tips' ) { - var v = clicked[ i ]; + if( clicked.every( alreadySelected ) ) + { + for( var i in clicked ) + selected_areas.splice( selected_areas.indexOf( clicked[ i ] ), 1 ); - if( addToList ) - selected_areas.push( v ); - else - selected_areas.splice( selected_areas.indexOf( v ), 1 ); + } else { + selected_areas = [ ...selected_areas, ...clicked ]; + } + } else { + var addToList = selected_areas.indexOf( sel[ 0 ] ) == -1; + + for( var i in clicked ) + { + var v = clicked[ i ]; + + if( addToList ) + selected_areas.push( v ); + else + selected_areas.splice( selected_areas.indexOf( v ), 1 ); + } } - } - - updateSelection(); - } ) - ); + + updateSelection(); + } ) + ); + } } $.unique( preloader ).forEach( function( img ){ @@ -5377,14 +5550,17 @@ function Pianos4( params ) div.append( map ); - div.append( - $( '' ) - .css( 'width', '100%' ) - .attr( 'id', 'pfsp_legend' ) - - .append( hover ) - .append( modes ) - ); + if( ! review ) + { + div.append( + $( '' ) + .css( 'width', '100%' ) + .attr( 'id', 'pfsp_legend' ) + + .append( hover ) + .append( modes ) + ); + } /* * Dialog box resizing @@ -5411,18 +5587,11 @@ function Pianos4( params ) dlgwidth += 25; dlgheight += 165; - var dlgopts = { - autoOpen: true, - modal: true, - title: title, - close: function() - { - $( this ).remove(); - }, - width: dlgwidth, - height: dlgheight, - resizable: false, - buttons: { + var buttons = null; + + if( ! review ) + { + buttons = { 'I dont know / None': function() { $( this ).dialog( 'close' ); @@ -5442,7 +5611,28 @@ function Pianos4( params ) selected_areas = []; updateSelection(); } + }; + } else { + buttons = { + 'Close': function() + { + $( this ).dialog( 'close' ); + }, + } + } + + var dlgopts = { + autoOpen: true, + modal: true, + title: title, + close: function() + { + $( this ).remove(); }, + width: dlgwidth, + height: dlgheight, + resizable: false, + buttons: buttons, open: function( event, ui ) { updateSelection( selected_areas ) @@ -5935,7 +6125,7 @@ function Pianos4( params ) } return ret; } - + var createUsersResultGrid = function( selector, data ) {