From 347f08c150cbd98ca36d6cd7a4e7e68c180ffa6f Mon Sep 17 00:00:00 2001 From: Chris Detsch Date: Thu, 24 Mar 2016 14:16:09 -0400 Subject: [PATCH] Changed the Student Profile so that the assignment history now is done in React. It now has an edit button that allows the user to edit the current assignment's reason. --- class/StudentProfileView.php | 4 +- .../AjaxEditAssignmentHistoryCommand.php | 60 +++++ .../AjaxGetAssignmentHistoryCommand.php | 107 ++++++++ .../studentProfileReact/assignmentHistory.jsx | 236 ++++++++++++++++++ node_modules/classnames/CONTRIBUTING.md | 21 ++ node_modules/classnames/HISTORY.md | 73 ++++++ node_modules/classnames/LICENSE | 21 ++ node_modules/classnames/README.md | 188 ++++++++++++++ node_modules/classnames/bind.js | 48 ++++ node_modules/classnames/bower.json | 37 +++ node_modules/classnames/dedupe.js | 98 ++++++++ node_modules/classnames/index.js | 48 ++++ node_modules/classnames/package.json | 85 +++++++ package.json | 26 ++ templates/admin/StudentProfile.tpl | 11 +- 15 files changed, 1059 insertions(+), 4 deletions(-) create mode 100644 class/command/AjaxEditAssignmentHistoryCommand.php create mode 100644 class/command/AjaxGetAssignmentHistoryCommand.php create mode 100644 javascript/studentProfileReact/assignmentHistory.jsx create mode 100644 node_modules/classnames/CONTRIBUTING.md create mode 100644 node_modules/classnames/HISTORY.md create mode 100644 node_modules/classnames/LICENSE create mode 100644 node_modules/classnames/README.md create mode 100644 node_modules/classnames/bind.js create mode 100644 node_modules/classnames/bower.json create mode 100644 node_modules/classnames/dedupe.js create mode 100644 node_modules/classnames/index.js create mode 100644 node_modules/classnames/package.json create mode 100644 package.json diff --git a/class/StudentProfileView.php b/class/StudentProfileView.php index ffc2cfc8..7da6e168 100644 --- a/class/StudentProfileView.php +++ b/class/StudentProfileView.php @@ -232,9 +232,7 @@ public function show() /********* * Assignment History * *********/ - $historyArray = StudentAssignmentHistory::getAssignments($this->student->getBannerId()); - $historyView = new StudentAssignmentHistoryView($historyArray); - $tpl['HISTORY'] = $historyView->show(); + // All done via react now. /********** diff --git a/class/command/AjaxEditAssignmentHistoryCommand.php b/class/command/AjaxEditAssignmentHistoryCommand.php new file mode 100644 index 00000000..1c0f020f --- /dev/null +++ b/class/command/AjaxEditAssignmentHistoryCommand.php @@ -0,0 +1,60 @@ +getId(); + + $this->updateAssignmentReason($reason, $id); + $this->updateHistoryReason($reason, $id); + + echo json_encode("success"); + exit; + } + + public function updateAssignmentReason($reason, $id) + { + $db = PdoFactory::getPdoInstance(); + $query = 'UPDATE hms_assignment set reason = :newReason where id = :id'; + $stmt = $db->prepare($query); + + $params = array( + 'newReason' => $reason, + 'id' => $id + ); + + $stmt->execute($params); + } + + public function updateHistoryReason($reason, $id) + { + $db = PdoFactory::getPdoInstance(); + $query = 'UPDATE hms_assignment_history set assigned_reason = :newReason where id = :id'; + $stmt = $db->prepare($query); + + $params = array( + 'newReason' => $reason, + 'id' => $id + ); + + $stmt->execute($params); + } +} diff --git a/class/command/AjaxGetAssignmentHistoryCommand.php b/class/command/AjaxGetAssignmentHistoryCommand.php new file mode 100644 index 00000000..33c3aaae --- /dev/null +++ b/class/command/AjaxGetAssignmentHistoryCommand.php @@ -0,0 +1,107 @@ +getBannerId()); + // var_dump($history);exit; + + $historyArray = array(); + $currentArray = array(); + + foreach ($history->getHistory() as $hNode) + { + $row = array(); + if(defined($hNode->assigned_reason)) + { + $assignedReason = constant($hNode->assigned_reason); // for pretty text purposes + } + else + { + $assignedReason = $hNode->assigned_reason; + } + $row['assignedReason'] = $assignedReason; + + if(defined($hNode->removed_reason)) + { + $removedReason = constant($hNode->removed_reason); // for pretty text purposes + } + else + { + $removedReason = $hNode->removed_reason; + } + $row['removedReason'] = $removedReason; + + if(!is_null($hNode->assigned_on)) + { + $assignedOn = date('M jS, Y \a\t g:ia', $hNode->assigned_on); + $assignedBy = $hNode->assigned_by; + } + else + { + $assignedOn = null; + $assignedBy = null; + } + $row['assignedOn'] = $assignedOn; + $row['assignedBy'] = $assignedBy; + + if(!is_null($hNode->removed_on)) + { + $removedOn = date('M jS, Y \a\t g:ia', $hNode->removed_on); + $removedBy = $hNode->removed_by; + } + else + { + $removedOn = null; + $removedBy = null; + } + $row['removedOn'] = $removedOn; + $row['removedBy'] = $removedBy; + + $bed = new HMS_Bed($hNode->getBedId()); + + $row['room'] = $bed->where_am_i(); + $row['term'] = Term::toString($hNode->term); + $row['id'] = $hNode->id; + + $historyArray[] = $row; + } + + $currentArray['term'] = $term; + + $assignment = HMS_Assignment::getAssignmentByBannerId($banner, $term); + if($assignment != null) + { + $currentArray['id'] = $assignment->getId(); + } + else + { + $currentArray['id'] = null; + } + + $returnData = array(); + $returnData['history'] = $historyArray; + $returnData['current'] = $currentArray; + + echo json_encode($returnData); + exit; + } +} diff --git a/javascript/studentProfileReact/assignmentHistory.jsx b/javascript/studentProfileReact/assignmentHistory.jsx new file mode 100644 index 00000000..fd87ded9 --- /dev/null +++ b/javascript/studentProfileReact/assignmentHistory.jsx @@ -0,0 +1,236 @@ + +var HistoryBox = React.createClass({ + getInitialState: function() + { + return ({history: [], current: []}); + }, + componentWillMount: function() + { + this.getHistory(); + }, + getHistory: function() + { + var inputData = {banner_id: bannerId}; + $.ajax({ + url : 'index.php?module=hms&action=AjaxGetAssignmentHistory', + type : 'GET', + datatype : 'json', + data : inputData, + success: function (data) { + var historyData = JSON.parse(data); + + this.setState({ + history : historyData.history, + current : historyData.current + }); + }.bind(this), + error: function() { + + }.bind(this) + }); + }, + render: function() + { + var rows; + var emptyMessage; + var data = this.state.history; + if(data.length != 0) + { + var refreshHistory = this.getHistory; + var currentAssignment = this.state.current; + rows = data.map(function(node){ + return ( + + ); + }); + } + else + { + emptyMessage = ( +

No Assignments found

+ ); + } + return( +
+ + + + + + + + + {rows} + +
RoomTermAssignmentUnassignment
+ {emptyMessage} +
+ ) + } +}); + +var TableRow = React.createClass({ + getInitialState: function() + { + return ({editing: false}); + }, + editAssignment: function() + { + this.setState({ + editing : true + }); + }, + cancel: function() + { + this.setState({ + editing : false + }); + }, + save: function(newReason) + { + var inputData = {reason: newReason, bannerId: this.props.bannerId, term: this.props.current.term}; + $.ajax({ + url: 'index.php?module=hms&action=AjaxEditAssignmentHistory', + type: 'POST', + dataType: 'json', + data: inputData, + success: function(data){ + this.props.refresh(); + this.setState({ + editing: false + }); + }.bind(this), + error: function(xhr, status, err){ + + }.bind(this) + }); + }, + render: function() + { + var dateStyle = { + fontSize : '11px', + color : '#7C7C7C' + }; + var noneStyle = {color: '#7C7C7C'} + + var assignment; + var unassignment; + + if(this.props.data.assignedReason == null) + { + assignment = ( + + None + + ); + } + else if(this.state.editing) + { + assignment = ( + + ); + } + else + { + var edit = ''; + if(this.props.current.id == this.props.data.id) + { + edit = ( + + ); + } + assignment = ( + + {this.props.data.assignedReason} by {this.props.data.assignedBy} {edit} +

+ on {this.props.data.assignedOn} + + ); + } + + if(this.props.data.removedReason == null) + { + unassignment = ( + + None + + ); + } + else + { + unassignment = ( + + {this.props.data.removedReason} by {this.props.data.removedBy} +

+ on {this.props.data.removedOn} + + ); + } + return( + + {this.props.data.room} + {this.props.data.term} + {assignment} + {unassignment} + + ); + } +}); + +var AssignmentSelect = React.createClass({ + cancel: function() + { + this.props.cancel(); + }, + save: function() + { + var reason = this.refs.assignmentDropdown.getDOMNode().value; + if(reason != '-1') + { + this.props.save(reason); + } + }, + render: function() + { + return ( + + + + + + ) + } +}); + + + +React.render( + , + document.getElementById('assignmentHistory') +); diff --git a/node_modules/classnames/CONTRIBUTING.md b/node_modules/classnames/CONTRIBUTING.md new file mode 100644 index 00000000..5904061e --- /dev/null +++ b/node_modules/classnames/CONTRIBUTING.md @@ -0,0 +1,21 @@ +# Contributing + +Thanks for your interest in classNames. Issues, PRs and suggestions welcome :) + +Before working on a PR, please consider the following: + +* Speed is a serious concern for this package as it is likely to be called a +significant number of times in any project that uses it. As such, new features +will only be accepted if they improve (or at least do not negatively impact) +performance. +* To demonstrate performance differences please set up a +[JSPerf](http://jsperf.com) test and link to it from your issue / PR. +* Tests must be added for any change or new feature before it will be accepted. + +A benchmark utilitiy is included so that changes may be tested against the +current published version. To run the benchmarks, `npm install` in the +`./benchmarks` directory then run `npm run benchmarks` in the package root. + +Please be aware though that local benchmarks are just a smoke-signal; they will +run in the v8 version that your node/iojs uses, while classNames is _most_ +often run across a wide variety of browsers and browser versions. diff --git a/node_modules/classnames/HISTORY.md b/node_modules/classnames/HISTORY.md new file mode 100644 index 00000000..758dc677 --- /dev/null +++ b/node_modules/classnames/HISTORY.md @@ -0,0 +1,73 @@ +# Changelog + +## v2.2.3 / 2016-01-05 + +* Updated `bind` variant to use `[].join(' ')` as per the main script in 2.2.2 + +## v2.2.2 / 2016-01-04 + +* Switched from string concatenation to `[].join(' ')` for a slight performance gain in the main function. + +## v2.2.1 / 2015-11-26 + +* Add deps parameter to the AMD module, fixes an issue using the Dojo loader, thanks [Chris Jordan](https://github.com/flipperkid) + +## v2.2.0 / 2015-10-18 + +* added a new `bind` variant for use with [css-modules](https://github.com/css-modules/css-modules) and similar abstractions, thanks to [Kirill Yakovenko](https://github.com/blia) + +## v2.1.5 / 2015-09-30 + +* reverted a new usage of `Object.keys` in `dedupe.js` that slipped through in the last release + +## v2.1.4 / 2015-09-30 + +* new case added to benchmarks +* safer `hasOwnProperty` check +* AMD module is now named, so you can do the following: + +``` +define(["classnames"], function (classNames) { + var style = classNames("foo", "bar"); + // ... +}); +``` + +## v2.1.3 / 2015-07-02 + +* updated UMD wrapper to support AMD and CommonJS on the same pacge + +## v2.1.2 / 2015-05-28 + +* added a proper UMD wrapper + +## v2.1.1 / 2015-05-06 + +* minor performance improvement thanks to type caching +* improved benchmarking and results output + +## v2.1.0 / 2015-05-05 + +* added alternate `dedupe` version of classNames, which is slower (10x) but ensures that if a class is added then overridden by a falsy value in a subsequent argument, it is excluded from the result. + +## v2.0.0 / 2015-05-03 + +* performance improvement; switched to `Array.isArray` for type detection, which is much faster in modern browsers. A polyfill is now required for IE8 support, see the Readme for details. + +## v1.2.2 / 2015-04-28 + +* license comment updates to simiplify certain build scenarios + +## v1.2.1 / 2015-04-22 + +* added safe exporting for requireJS usage +* clarified Bower usage and instructions + +## v1.2.0 / 2015-03-17 + +* added comprehensive support for array arguments, including nested arrays +* simplified code slightly + +## Previous + +Please see the git history for the details of previous versions. diff --git a/node_modules/classnames/LICENSE b/node_modules/classnames/LICENSE new file mode 100644 index 00000000..e6620b58 --- /dev/null +++ b/node_modules/classnames/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Jed Watson + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/node_modules/classnames/README.md b/node_modules/classnames/README.md new file mode 100644 index 00000000..b1653c25 --- /dev/null +++ b/node_modules/classnames/README.md @@ -0,0 +1,188 @@ +Classnames +=========== + +[![Version](http://img.shields.io/npm/v/classnames.svg)](https://www.npmjs.org/package/classnames) +[![Build Status](https://travis-ci.org/JedWatson/classnames.svg?branch=master)](https://travis-ci.org/JedWatson/classnames) + +A simple javascript utility for conditionally joining classNames together. + +Install with npm or Bower. + +```sh +npm install classnames +``` + +Use with node.js, browserify or webpack: + +```js +var classNames = require('classnames'); +classNames('foo', 'bar'); // => 'foo bar' +``` + +Alternatively, you can simply include `index.js` on your page with a standalone ` + + + + +