Jump to content

Graham Quince

Administrators
  • Posts

    1,936
  • Joined

  • Last visited

Personal Information

  • School
    Frog Education

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

Graham Quince's Achievements

  1. Graham Quince

    SSO's?

    Yes, please. The Service Desk will need to configure the settings in Frog and I think they also have to contact SchoolCloud to have them configure settings.
  2. Graham Quince

    SSO's?

    Just Staff SSO, I'm afraid.
  3. Hi, We are aware of this issue, and it's been addressed. Unfortunately the fix does require an update to your platforms as well as a release to the app. It's expected to be out in the next update. It's currently in testing.
  4. it came very close, but all the extra requirements you added meant it was becoming too difficult to debug - so I gave up. Sorry.
  5. Yeah - this is why I need help testing it - I need real world examples so I can spot the differences in the API returned data. I know I could ask the Devs, but they are pretty busy at the moment.
  6. Send me a message to where it is. Did you set the UUID?
  7. The above code works for FrogCode widgets, this code works for the HTML widgetL <script> $('div[data-content-uuid="SELECT_USER_WIDGET_CONTENT_UUID"]').on('broadcast.selectedUser',function(el, ev) { console.log(ev); console.log("user name = "+ev.model.displayname); console.log("user uuid = "+ev.model.uuid); }); </script>
  8. The things I do for you: <style> .assignmentReportsTables td, .assignmentReportsTables th { text-align: center; vertical-align: middle; line-height: 25px; height: 54px; } .assignmentReportsTables { font-size: 16px; line-height: 25px; } .hw { min-width: 50px; height: 50px; line-height: 25px; vertical-align: middle; overflow: hidden; border: 1px solid #CCCCCC; text-align: center; background: #ffffff; float: left; margin-right: 2px; margin-bottom: 2px; } .hw:hover { background: #CCCCCC; } .hw .status { position: relative; background-size: cover; height: 24px; width: 24px; margin-left: auto; margin-right: auto; font-weight: bold; } .hw .bottom-right { position: absolute; right: -14px; bottom: -1px; width: 15px; height: 15px; line-height: 15px; font-size: 13px; background-color: #000; color: #ffffff; } .hw .late { background: #FF0000; } .hw .absent { background: #000000; } .hws { width: 50%; } .childHeading { font-size: 25px; font-weight: bold; line-height: 35px; } </style> <div class="AssignmentSummary"></div> <script> var startOfYear = moment('1/9/2021 1:00', "D/M/YYYY H:mm").unix(); var AssignmentSummary = arguments[0].find('.AssignmentSummary'); var user = FrogOS ? FrogOS.getUser() : self.getUser(); function getAssignments(view,child_uuid) { var self = this; var assignmentsObject = {}; AssignmentSummary.empty(); var data = { end_from: startOfYear, end_to: parseInt(moment()/1000), status: 'closed', order: 'start desc', } if (view !== 'student') { data = { end_from: startOfYear, end_to: parseInt(moment()/1000), status: 'closed', order: 'start desc', assigned_user: child_uuid } } AssignmentSummary.append( '<table class="assignmentReportsTables table-hover table-bordered table sum_'+child_uuid+'">'+ '<tr>'+ '<th>Subject</th>'+ '<th>No. of assignments</th>'+ '<th>Average Mark</th>'+ '<th>Late Hand In</th>'+ '<th>Not done</th>'+ '<th>Homeworks</th>'+ '</tr>'+ '</table>' ); var myMarks = AssignmentSummary.find('.sum_'+child_uuid); FrogOS.fdp({ url: 'assignment/getAssigned', data }).done(function(response) { var homeworks = response.response.assignments; var SubjectsArray = []; $.each(homeworks, function(index,homework) { var subject = homework.assignment.subject.name; var subjectClass = subject.replace(/\s/g, "").replace("&", ""); if (SubjectsArray.indexOf(subject) < 0) { // Add all unique subjects as a row SubjectsArray.push(subject); myMarks.append( '<tr>'+ '<td>'+subject+'</td>'+ '<td class="'+subjectClass+'_total" >0</td>'+ '<td class="'+subjectClass+'_average" >0</td>'+ '<td class="'+subjectClass+'_late">0</td>'+ '<td class="'+subjectClass+'_notdone">0</td>'+ '<td class="'+subjectClass+'_hws hws"></td>'+ '</tr>' ) assignmentsObject[subject] = { total:0, massMarks: 0, totalMarked: 0, late: 0, notdone: 0 } }; // end of all unique subjects var lateAbsent = ''; var completed = homework.user_info.completed; var duedate = homework.assignment.end; if (completed > duedate) { lateAbsent = '<div class="bottom-right late">L</div>'; assignmentsObject[subject].late += 1; } if (homework.user_info.status == "absent") { lateAbsent = '<div class="bottom-right absent">A</div>'; } if (homework.user_info.status == "notdone") { assignmentsObject[subject].notdone += 1; } assignmentsObject[subject].total += 1; var markscheme = ''; if (homework.user_info.mark !== null) { // IF the homework has been marked if (homework.assignment.mark_scheme.name !== 'markscheme.percentage.name' ) { var grades = homework.assignment.mark_scheme.data_values.grades; assignmentsObject[subject].massMarks += parseInt(grades[homework.user_info.mark]); } var markscheme = ' (Mark Scheme: '+homework.assignment.mark_scheme.name+')'; if (markscheme == ' (Mark Scheme: markscheme.percentage.name)') { assignmentsObject[subject].massMarks += homework.user_info.mark; markscheme = ' (Mark Scheme: Percent)'; } assignmentsObject[subject].totalMarked += 1; } else { // end of if homework marked homework.user_info.mark = 'N/A'; } if (homework.user_info.status == 'ontime') { homework.user_info.status = 'ready'; // makes a tick } if (homework.user_info.status == null) { homework.user_info.status = 'inprogress'; // makes a grey tick } if (homework.user_info.status && homework.user_info.mark == "N/A") { homework.user_info.status = "notdone"; } myMarks.find('.'+subjectClass+'_total').text(assignmentsObject[subject].total); myMarks.find('.'+subjectClass+'_average').text(parseInt(assignmentsObject[subject].massMarks/assignmentsObject[subject].totalMarked)+'%'); if (myMarks.find('.'+subjectClass+'_average').text() == 'NaN%') { myMarks.find('.'+subjectClass+'_average').text('-'); } myMarks.find('.'+subjectClass+'_late').text(parseInt(100*assignmentsObject[subject].late/assignmentsObject[subject].total)+'%'); myMarks.find('.'+subjectClass+'_notdone').text(parseInt(100*assignmentsObject[subject].notdone/assignmentsObject[subject].total)+'%'); myMarks.find('.'+subjectClass+'_hws').append( '<div class="hw" title="'+homework.assignment.name+markscheme+'" data-assignment-link="' + homework.assignment.link + '">'+ homework.user_info.mark+ '<div class="center status ui-svg-icon-'+homework.user_info.status+'">'+ lateAbsent+ '</div>' ); }) // end of $.each }).fail(function(e) { console.log("FAILED"); }); }; // End of GetAssignments function $(AssignmentSummary).on('click', '.hw', function(el){ $(this).trigger('os.app.siteviewer', { data: { site: el.currentTarget.dataset.assignmentLink } }); }); if (user.profile.type == 'student') { getAssignments('student',user.uuid); } else { $('div[data-content-uuid="SELECT_USER_WIDGET_CONTENT_UUID"]').on('broadcast.selectedUser',function(el, ev) { getAssignments('parent',ev.model.uuid); }); } </script>
  9. Almost a year and no issues. I think it's safe to say we've all moved on
  10. Just tidying up the forum. I believe this issue was sorted through investigation with the service desk
  11. If you hover the mouse over an assignment tile, it's displayed along with the mark scheme
  12. Just been experimenting with this for a school and thought others might like the idea: <style> .assignmentReportsTables td, .assignmentReportsTables th { text-align: center; vertical-align: middle; line-height: 25px; height: 54px; } .assignmentReportsTables { font-size: 16px; line-height: 25px; } .hw { min-width: 50px; height: 50px; line-height: 25px; vertical-align: middle; overflow: hidden; border: 1px solid #CCCCCC; text-align: center; background: #ffffff; float: left; margin-right: 2px; margin-bottom: 2px; } .hw:hover { background: #CCCCCC; } .hw .status { position: relative; background-size: cover; height: 24px; width: 24px; margin-left: auto; margin-right: auto; font-weight: bold; } .hw .bottom-right { position: absolute; right: -14px; bottom: -1px; width: 15px; height: 15px; line-height: 15px; font-size: 13px; background-color: #000; color: #ffffff; } .hw .late { background: #FF0000; } .hw .absent { background: #000000; } .hws { width: 50%; } .childHeading { font-size: 25px; font-weight: bold; line-height: 35px; } </style> <div class="AssignmentSummary"></div> <script> var startOfYear = moment('1/9/2021 1:00', "D/M/YYYY H:mm").unix(); var AssignmentSummary = arguments[0].find('.AssignmentSummary'); var user = FrogOS ? FrogOS.getUser() : self.getUser(); function getAssignments(view,child_uuid) { var self = this; var assignmentsObject = {}; var myMarksSpace = AssignmentSummary; var data = { end_from: startOfYear, end_to: parseInt(moment()/1000), status: 'closed', order: 'start desc', } if (view !== 'student') { data = { end_from: startOfYear, end_to: parseInt(moment()/1000), status: 'closed', order: 'start desc', assigned_user: child_uuid } myMarksSpace = AssignmentSummary.find('.child_'+child_uuid); } myMarksSpace.append( '<table class="assignmentReportsTables table-hover table-bordered table sum_'+child_uuid+'">'+ '<tr>'+ '<th>Subject</th>'+ '<th>No. of assignments</th>'+ '<th>Average Mark</th>'+ '<th>Late Hand In</th>'+ '<th>Not done</th>'+ '<th>Homeworks</th>'+ '</tr>'+ '</table>' ); var myMarks = myMarksSpace.find('.sum_'+child_uuid); FrogOS.fdp({ url: 'assignment/getAssigned', data }).done(function(response) { var homeworks = response.response.assignments; var SubjectsArray = []; $.each(homeworks, function(index,homework) { /*if (homework.assignment.subject.name == "Chemistry") { console.log(homework); }*/ var subject = homework.assignment.subject.name; var subjectClass = subject.replace(/\s/g, "").replace("&", ""); if (SubjectsArray.indexOf(subject) < 0) { // Add all unique subjects as a row SubjectsArray.push(subject); myMarks.append( '<tr>'+ '<td>'+subject+'</td>'+ '<td class="'+subjectClass+'_total" >0</td>'+ '<td class="'+subjectClass+'_average" >0</td>'+ '<td class="'+subjectClass+'_late">0</td>'+ '<td class="'+subjectClass+'_notdone">0</td>'+ '<td class="'+subjectClass+'_hws hws"></td>'+ '</tr>' ) assignmentsObject[subject] = { total:0, massMarks: 0, totalMarked: 0, late: 0, notdone: 0 } }; // end of all unique subjects var lateAbsent = ''; var completed = homework.user_info.completed; var duedate = homework.assignment.end; if (completed > duedate) { lateAbsent = '<div class="bottom-right late">L</div>'; assignmentsObject[subject].late += 1; } if (homework.user_info.status == "absent") { lateAbsent = '<div class="bottom-right absent">A</div>'; } if (homework.user_info.status == "notdone") { assignmentsObject[subject].notdone += 1; } assignmentsObject[subject].total += 1; var markscheme = ''; if (homework.user_info.mark !== null) { // IF the homework has been marked if (homework.assignment.mark_scheme.name !== 'markscheme.percentage.name' ) { var grades = homework.assignment.mark_scheme.data_values.grades; assignmentsObject[subject].massMarks += parseInt(grades[homework.user_info.mark]); } var markscheme = ' (Mark Scheme: '+homework.assignment.mark_scheme.name+')'; if (markscheme == ' (Mark Scheme: markscheme.percentage.name)') { assignmentsObject[subject].massMarks += homework.user_info.mark; markscheme = ' (Mark Scheme: Percent)'; } assignmentsObject[subject].totalMarked += 1; } else { // end of if homework marked homework.user_info.mark = 'N/A'; } if (homework.user_info.status == 'ontime') { homework.user_info.status = 'ready'; // makes a tick } if (homework.user_info.status == null) { homework.user_info.status = 'inprogress'; // makes a grey tick } if (homework.user_info.status && homework.user_info.mark == "N/A") { homework.user_info.status = "notdone"; } myMarks.find('.'+subjectClass+'_total').text(assignmentsObject[subject].total); myMarks.find('.'+subjectClass+'_average').text(parseInt(assignmentsObject[subject].massMarks/assignmentsObject[subject].totalMarked)+'%'); if (myMarks.find('.'+subjectClass+'_average').text() == 'NaN%') { myMarks.find('.'+subjectClass+'_average').text('-'); } myMarks.find('.'+subjectClass+'_late').text(parseInt(100*assignmentsObject[subject].late/assignmentsObject[subject].total)+'%'); myMarks.find('.'+subjectClass+'_notdone').text(parseInt(100*assignmentsObject[subject].notdone/assignmentsObject[subject].total)+'%'); myMarks.find('.'+subjectClass+'_hws').append( '<div class="hw" title="'+homework.assignment.name+markscheme+'" data-assignment-link="' + homework.assignment.link + '">'+ homework.user_info.mark+ '<div class="center status ui-svg-icon-'+homework.user_info.status+'">'+ lateAbsent+ '</div>' ); }) // end of $.each }).fail(function(e) { console.log("FAILED"); }); }; // End of GetAssignments function $(AssignmentSummary).on('click', '.hw', function(el){ $(this).trigger('os.app.siteviewer', { data: { site: el.currentTarget.dataset.assignmentLink } }); }); if (user.profile.type == 'student') { getAssignments('student',user.uuid); } else { Frog.Model.api('users.getChildren').done(function(listResponse) { var children = listResponse.data; $.each(children, function(index,child) { AssignmentSummary.append( '<div class="childHeading">'+ child.displayname+"'s Assignment Summary</div>"+ '<div class="child_'+child.uuid+'">'+ '</div><hr>' ); getAssignments('parent',child.uuid); }); }); } </script> I'm not sure I'll turn this into a widget as there's so many parameters to adapt - I don't think I've caught all the marking possibilities yet either. Each individual homework tile opens the homework, I had to include markschemes in the tile's Title tag as it was possible to have a 5 in GCSE and another homework have a 5 for Effort. I'd be interested in feedback on this, if anyone wants to try it out.
  13. Here's the code snippet required should you wish to trigger a growl in FrogLearn: Frog.Controller.prototype.growl('Quick alert','HTML Widget','app-name',{time:5000, icon: 'sites/widget/1D88867A2001BB391A801F0DE1E6D50A0244F78C1CDBCD72/icon.png'}); (The time variable is the length of time in milliseconds that the growl will appear for.)
  14. I always struggle to remember the format needed to call an API, so thought it might make sense to have them here for copy-and-paste-and-adapt purposes Internal* Frog API (GET) Frog.Model.api('API_URL_GOES_HERE', { param1: 'PARAM1', param2: 'PARAM2' }).done(function(response) { // do something with the response data var data = response; }).fail(function(e) { // Report Error console.log("failed"); }); Internal Frog API (POST) Frog.Model.api('API_URL_GOES_HERE', { param1: 'PARAM1', param2: 'PARAM2' },{ type: 'POST' }).done(function(response) { // do something with the response data var data = response; }).fail(function(e) { // Report Error console.log("failed"); }); FDP API (GET) FrogOS.fdp({ url: 'API_URL_GOES_HERE', path: '/api/fdp/2/', data: { param1: 'PARAM1', param2: 'PARAM2' } }).done(function(response) { // do something with the response data var data = response; }).fail(function(e) { // Report Error console.log("failed"); }); FDP API (POST) FrogOS.fdp({ url: 'API_URL_GOES_HERE', path: '/api/fdp/2/', type: 'POST', data: { param1: 'PARAM1', param2: 'PARAM2' } }).done(function(response) { // do something with the response data var data = response; }).fail(function(e) { // Report Error console.log("failed"); }); * Internal APIs are subject to change by our developers. FDP APIs are set in stone. You can use the Network tab in your browser's Developer Console to identify an internal API and its required parameters. On each of your Frog platforms, there is an application called FDP API Reference (if it's not visible, you may need to publish this via Package Manager). Within this, you'll find a list of all the FDP APIs, their URLs and available parameters. The one element this application lacks is the above example, but hopefully this will help with that.
×
×
  • Create New...