Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dev/10.1.0 #1545

Merged
merged 82 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
82 commits
Select commit Hold shift + click to select a range
f10c8e5
Hides embedded only option and increases dialog height
cayb0rg Oct 5, 2023
7cc9878
Sets user's instances to guest access when authors become students
cayb0rg Oct 5, 2023
245e2c6
Adds error handling to support instance manager when trying to remove…
cayb0rg Oct 11, 2023
85cc43e
Hide embed-only by default
cayb0rg Oct 11, 2023
49aea4a
Move student check outside function
cayb0rg Oct 11, 2023
e35432c
piggyback on my-widgets-page pagination hook
cayb0rg Oct 11, 2023
6a4ce82
Remove function to set instances to guest mode
cayb0rg Oct 17, 2023
1b2fab4
Converts modal component from class-based to functional
clpetersonucf Oct 11, 2023
42feccd
Tweaks to alert modal component styling. Replaced invalidLogin handli…
clpetersonucf Oct 11, 2023
4bd7a61
Merge master into issue/settings-dialog
cayb0rg Oct 18, 2023
136de59
Update settings dialog view/edit permissions for once-author-now-stud…
cayb0rg Oct 18, 2023
2260369
Update attempts slider
cayb0rg Oct 18, 2023
e94da59
Merge master into issue/1508-pagination
cayb0rg Oct 19, 2023
7b87acb
Merge branch 'dev/10.0.1' into issue/1508-pagination
cayb0rg Oct 19, 2023
9c128bb
Increase pagination speeds and add loading icon
cayb0rg Oct 19, 2023
1fa95ab
Merge branch 'dev/10.0.1' into issue/1508-pagination
cayb0rg Oct 24, 2023
7c1e441
Apply pagination rules to all components using apiSearchUsers and fix…
cayb0rg Oct 24, 2023
afeebca
Update tests for search user
cayb0rg Oct 24, 2023
6d754c9
Remove log
cayb0rg Oct 24, 2023
5a81bff
User search fix and collaborator results scroll
cayb0rg Oct 24, 2023
ac422c9
Remove user tests
cayb0rg Oct 24, 2023
9b080cb
Merging in upstream changes
clpetersonucf Oct 26, 2023
4a7707f
Add guides.css to MWD
cayb0rg Oct 31, 2023
d467ad2
Merge in dev/10.1.0
cayb0rg Oct 31, 2023
bf51d03
Merge in dev/10.1.0
cayb0rg Oct 31, 2023
19b4642
improves play.auth string check in user admin panel
clpetersonucf Nov 14, 2023
3223663
Merge pull request #1539 from cayb0rg/MWD-guide-css
clpetersonucf Nov 14, 2023
f8c8987
Bumps MWD to v0.3.0
clpetersonucf Nov 14, 2023
62cf869
Modifies materia-app dockerfile to nullify logging from php-fpm's acc…
clpetersonucf Nov 15, 2023
e240a04
replaces node sass with dart sass
Dec 15, 2023
3b5c6ae
Merge pull request #1551 from cayb0rg/remove-node-sass
clpetersonucf Jan 3, 2024
cede029
Lockfile cleanup after node-sass removal
clpetersonucf Jan 3, 2024
9978e88
Merge pull request #1544 from clpetersonucf/issue/1543-user-admin-aut…
clpetersonucf Jan 4, 2024
40c636d
Adds debounce & fixes individual user search in score summary. Two sm…
clpetersonucf Jan 8, 2024
9165b7d
Adds conditionally rendered content when user search returns an empty…
clpetersonucf Jan 8, 2024
d7aabf0
Merge pull request #1537 from clpetersonucf/issue/improved-invalid-lo…
clpetersonucf Jan 9, 2024
be147dc
Adjusted scoreTableContainer relative position
clpetersonucf Jan 9, 2024
f38dd85
Merge pull request #1554 from clpetersonucf/issue/1550-fix-student-se…
clpetersonucf Jan 9, 2024
9860c9a
Adds modified property to paginated instance API response. Updates wi…
clpetersonucf Jan 9, 2024
5279fc5
Modified addl instance properties to be cast as ints instead of strin…
clpetersonucf Jan 9, 2024
eaddcdf
Modified property in API response unnecessary, pulling it back out
clpetersonucf Jan 9, 2024
c7b5d7a
Forgot console logs
clpetersonucf Jan 9, 2024
699e343
Merge pull request #1556 from clpetersonucf/issue/1553-fix-widget-set…
clpetersonucf Jan 10, 2024
e29921f
Merge in dev/10.1.0
cayb0rg Jan 11, 2024
10ac024
Fix student viewing + responsiveness
cayb0rg Jan 11, 2024
21e6505
Fix attempts selector
cayb0rg Jan 11, 2024
f6701dd
Remove debugging and other stuff accidentally merged in
cayb0rg Jan 11, 2024
63b2a9b
Adds edge case handling to ensure the widget-player component always …
clpetersonucf Jan 11, 2024
313d4cb
Replaces overengineered deferment of queueProcessing flag with score …
clpetersonucf Jan 12, 2024
91b5bfe
Fixes sloppy async function reference
clpetersonucf Jan 12, 2024
eeec4d7
Adds triage functionality to grab LTI token from play instance when n…
clpetersonucf Jan 13, 2024
45733c2
Improves triage code to address missing condition match & limit runni…
clpetersonucf Jan 16, 2024
56096bf
Improved existence check of ev_data array keys in triage code
clpetersonucf Jan 17, 2024
6b4d4e9
Log cleanup
clpetersonucf Jan 17, 2024
0b7fa9c
Merge pull request #6 from clpetersonucf/emergency-hotfix/missing-ses…
clpetersonucf Jan 17, 2024
4b1c3e7
Cleans up triage code and formalizes new static methods in ltievents
clpetersonucf Jan 22, 2024
a095e78
Merge pull request #1548 from clpetersonucf/feature/nullify-log-spam
clpetersonucf Jan 23, 2024
8e6886e
Fix ressponsive styling and remove debug logs
cayb0rg Jan 25, 2024
e3427cf
split hooks, rename funcs + prevent search on page load
cayb0rg Jan 25, 2024
486d3b4
Merge branch 'dev/10.1.0' into issue/1508-pagination
cayb0rg Jan 25, 2024
dcd4ca1
Merge pull request #1560 from clpetersonucf/issue/1558-score-screen-u…
clpetersonucf Jan 25, 2024
a2f17a9
Update react-datepicker to 5.0.0 to remove wrapping issue
cayb0rg Jan 29, 2024
a0b19a0
Update my-widgets-settings-dialog.jsx
cayb0rg Jan 29, 2024
6ebaef7
Merge pull request #1540 from cayb0rg/issue/settings-dialog
clpetersonucf Jan 30, 2024
6e3ab86
Merge branch 'dev/10.1.0' into issue/1508-pagination
cayb0rg Jan 31, 2024
d735b60
Fix issue with double instances and reduce default limit
cayb0rg Jan 31, 2024
6e1bf19
Reduce another default limit
cayb0rg Jan 31, 2024
34815ba
prod and dev webpack configs updated to split common dependencies in …
clpetersonucf Jan 31, 2024
7bb0225
Filters js bundling optimizations to ignore -core files
clpetersonucf Jan 31, 2024
7b65d3b
Adds commons.js to MWD manifest
clpetersonucf Jan 31, 2024
0c9200e
Add additional order_by query to get predictable results
cayb0rg Feb 1, 2024
c3549e0
Remove unnecessary front-end sort
cayb0rg Feb 1, 2024
7598e84
Add test
cayb0rg Feb 1, 2024
ff99e23
Merge pull request #1541 from cayb0rg/issue/1508-pagination
clpetersonucf Feb 1, 2024
39dbf74
Merge pull request #1563 from clpetersonucf/issue/1562-js-import-opti…
clpetersonucf Feb 1, 2024
98f676e
Modifies dev & prod webpack configs to properly emit commons js in pr…
clpetersonucf Feb 5, 2024
f6cb1a3
Adds commons css to main group, which previously wasn't defined
clpetersonucf Feb 6, 2024
95dfc9b
Instance duplicate sets embedded flags to false. Added react import i…
clpetersonucf Feb 6, 2024
84bcba1
Fix saving settings as grandfathered-in student and prevent students …
cayb0rg Feb 6, 2024
70f6846
Prevent students from changing to normal mode when they're owners
cayb0rg Feb 6, 2024
89b690f
Merge branch 'dev/10.1.0' of github.com:ucfopen/Materia into dev/10.1.0
cayb0rg Feb 6, 2024
730bea4
Merge pull request #1564 from cayb0rg/dev/10.1.0
clpetersonucf Feb 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions fuel/app/classes/controller/api/admin.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,13 +69,20 @@ public function post_user($user_id)
return \Service_User::update_user($user_id, $user);
}

public function get_widget_search(string $input)
public function get_instance_search(string $input, string $page_number)
{
$input = trim($input);
$input = urldecode($input);
$page_number = (int) $page_number;
//no need to search if for some reason an empty string is passed
if ($input == '') return [];
return \Materia\Widget_Instance_Manager::get_search($input);
if ($input == '')
{
return [
'pagination' => [],
'next_page' => $page_number
];
}
return \Materia\Widget_Instance_Manager::get_paginated_instance_search($input, $page_number);
}

public function get_extra_attempts(string $inst_id)
Expand Down
100 changes: 64 additions & 36 deletions fuel/app/classes/materia/api/v1.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ static public function widget_instances_get($inst_ids = null, bool $deleted = fa
*
* @return array of objects containing total_num_pages and widget instances that are visible to the user.
*/
static public function widget_paginate_instances_get($page_number = 0)
static public function widget_paginate_user_instances_get($page_number = 0)
{
if (\Service_User::verify_session() !== true) return Msg::no_login();
$data = Widget_Instance_Manager::get_paginated_for_user(\Model_User::find_current_id(), $page_number);
$data = Widget_Instance_Manager::get_paginated_instances_for_user(\Model_User::find_current_id(), $page_number);
return $data;
}

Expand Down Expand Up @@ -218,7 +218,7 @@ static public function widget_instance_new($widget_id=null, $name=null, $qset=nu
* @param int $close_at
* @param int $attempts
* @param bool $guest_access
* @param bool $is_student_made
* @param bool $is_student_made // NOT USED
*
* @return array An associative array with details about the save
*/
Expand All @@ -237,6 +237,10 @@ static public function widget_instance_update($inst_id=null, $name=null, $qset=n
// student made widgets are locked forever
if ($inst->is_student_made)
{
if ($guest_access === false)
{
return new Msg('Student-made widgets must stay in guest access mode.', 'Student Made', 'error', false);
}
$attempts = -1;
$guest_access = true;
}
Expand Down Expand Up @@ -328,36 +332,42 @@ static public function widget_instance_update($inst_id=null, $name=null, $qset=n
}
if ($guest_access !== null)
{
if ($inst->guest_access != $guest_access)
{
$activity = new Session_Activity([
'user_id' => \Model_User::find_current_id(),
'type' => Session_Activity::TYPE_EDIT_WIDGET_SETTINGS,
'item_id' => $inst_id,
'value_1' => 'Guest Access',
'value_2' => $guest_access
]);
$activity->db_store();
}
$inst->guest_access = $guest_access;
// when disabling guest mode on a widget, make sure no students have access to that widget
if ( ! $guest_access)
// if the user is a student and they're not the owner, they can't do anything
// if the user is a student and they're the owner, they're allowed to set it to guest access
if (($inst->user_id == \Model_User::find_current_id() && $guest_access) || ! Perm_Manager::is_student(\Model_User::find_current_id()))
{
$access = Perm_Manager::get_all_users_explicit_perms($inst_id, Perm::INSTANCE)['widget_user_perms'];
foreach ($access as $user_id => $user_perms)
if ($inst->guest_access != $guest_access)
{
if (Perm_Manager::is_student($user_id))
$activity = new Session_Activity([
'user_id' => \Model_User::find_current_id(),
'type' => Session_Activity::TYPE_EDIT_WIDGET_SETTINGS,
'item_id' => $inst_id,
'value_1' => 'Guest Access',
'value_2' => $guest_access
]);
$activity->db_store();
}
$inst->guest_access = $guest_access;
// when disabling guest mode on a widget, make sure no students have access to that widget
if ( ! $guest_access)
{
$access = Perm_Manager::get_all_users_explicit_perms($inst_id, Perm::INSTANCE)['widget_user_perms'];
foreach ($access as $user_id => $user_perms)
{
\Model_Notification::send_item_notification(\Model_user::find_current_id(), $user_id, Perm::INSTANCE, $inst_id, 'disabled', null);
Perm_Manager::clear_user_object_perms($inst_id, Perm::INSTANCE, $user_id);
if (Perm_Manager::is_student($user_id) && $user_id != $inst->user_id)
{
\Model_Notification::send_item_notification(\Model_user::find_current_id(), $user_id, Perm::INSTANCE, $inst_id, 'disabled', null);
Perm_Manager::clear_user_object_perms($inst_id, Perm::INSTANCE, $user_id);
}
}
}
}
}

if ($embedded_only !== null)
{
if ($inst->embedded_only != $embedded_only)
// if current user is student, they cannot change embedded_only
if ($inst->embedded_only != $embedded_only && ! Perm_Manager::is_student(\Model_User::find_current_id()))
{
$activity = new Session_Activity([
'user_id' => \Model_User::find_current_id(),
Expand All @@ -367,8 +377,9 @@ static public function widget_instance_update($inst_id=null, $name=null, $qset=n
'value_2' => $embedded_only
]);
$activity->db_store();

$inst->embedded_only = $embedded_only;
}
$inst->embedded_only = $embedded_only;
}

try
Expand Down Expand Up @@ -662,11 +673,12 @@ static public function guest_widget_instance_scores_get($inst_id, $play_id)
*/
static public function play_logs_get($inst_id, $semester = 'all', $year = 'all', $page_number=1)
{
if ( ! Util_Validator::is_valid_hash($inst_id)) return Msg::invalid_input($inst_id);
if ( ! Util_Validator::is_valid_hash($inst_id)) return Msg::invalid_input($inst_id);
if (\Service_User::verify_session() !== true) return Msg::no_login();
if ( ! static::has_perms_to_inst($inst_id, [Perm::VISIBLE, Perm::FULL])) return Msg::no_perm();
$is_student = ! \Service_User::verify_session(['basic_author', 'super_user']);

$data = Session_Play::get_by_inst_id_paginated($inst_id, $semester, $year, $page_number);
$data = Session_Play::get_by_inst_id_paginated($inst_id, $semester, $year, $page_number, $is_student);
return $data;
}

Expand Down Expand Up @@ -881,23 +893,39 @@ static public function semester_date_ranges_get()
return Utils::get_date_ranges();
}

static public function users_search($search)
/**
* Paginated search for users that match input
*
* @param string Search query
* @param string Page number
* @return array List of users
*/
static public function users_search($input, $page_number = 0)
{
if (\Service_User::verify_session() !== true) return Msg::no_login();

$user_objects = \Model_User::find_by_name_search($search);
$user_arrays = [];
$items_per_page = 50;
$offset = $items_per_page * $page_number;

// query DB for only a single page + 1 item
$displayable_items = \Model_User::find_by_name_search($input, $offset, $items_per_page + 1);

$has_next_page = sizeof($displayable_items) > $items_per_page ? true : false;

if ($has_next_page) array_pop($displayable_items);

// scrub the user models with to_array
if (count($user_objects))
foreach ($displayable_items as $key => $person)
{
foreach ($user_objects as $key => $person)
{
$user_arrays[$key] = $person->to_array();
}
$displayable_items[$key] = $person->to_array();
}

return $user_arrays;
$data = [
'pagination' => $displayable_items,
];

if ($has_next_page) $data['next_page'] = $page_number + 1;

return $data;
}
/**
* Gets information about the current user
Expand Down
4 changes: 2 additions & 2 deletions fuel/app/classes/materia/perm/manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ static public function is_super_user()
// The session caching has been removed due to issues related to the cache when the role is added or revoked
// Ideally we can still find a way to cache this and make it more performant!!
return (\Fuel::$is_cli === true && ! \Fuel::$is_test) || self::does_user_have_role([\Materia\Perm_Role::SU]);

}

/**
Expand Down Expand Up @@ -351,10 +351,10 @@ static public function remove_users_from_roles_system_only(Array $user_ids = [],
->execute();
}
}

return $success;
}


/*
********************** User to Object Rights ***************************************
*/
Expand Down
41 changes: 37 additions & 4 deletions fuel/app/classes/materia/session/play.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,7 +213,7 @@ public function resume($play_id)
* Must be fast because it can be asked to retrieve large data sets
*
*/
public static function get_by_inst_id($inst_id, $semester='all', $year='all')
public static function get_by_inst_id($inst_id, $semester='all', $year='all', $is_student=false)
{
if ($semester != 'all' && $year != 'all')
{
Expand All @@ -230,7 +230,23 @@ public static function get_by_inst_id($inst_id, $semester='all', $year='all')

if (is_null($plays))
{
$query = \DB::select(
// if user is student, do not query user information
if ($is_student)
{
$query = \DB::select(
's.id',
['s.created_at', 'time'],
['s.is_complete', 'done'],
['s.percent', 'perc'],
['s.elapsed', 'elapsed'],
['s.qset_id', 'qset_id']
)
->from(['log_play', 's'])
->where('s.inst_id', $inst_id);
}
else
{
$query = \DB::select(
's.id',
['s.created_at', 'time'],
['s.is_complete', 'done'],
Expand All @@ -246,6 +262,7 @@ public static function get_by_inst_id($inst_id, $semester='all', $year='all')
->join(['users', 'u'], 'LEFT OUTER')
->on('u.id', '=', 's.user_id')
->where('s.inst_id', $inst_id);
}

if (isset($date))
{
Expand All @@ -256,14 +273,28 @@ public static function get_by_inst_id($inst_id, $semester='all', $year='all')

\Cache::set('play-logs.'.$inst_id.'.'.$cache_id, $plays);
}
else
{
// if user is student, do not show user information
if ($is_student)
{
foreach ($plays as &$play)
{
$play['user_id'] = 0;
unset($play['first']);
unset($play['last']);
unset($play['username']);
}
}
}

return $plays;
}

public static function get_by_inst_id_paginated($inst_id, $semester='all', $year='all', $page_number=1)
public static function get_by_inst_id_paginated($inst_id, $semester='all', $year='all', $page_number=1, $is_student=false)
{
$items_per_page = 100;
$data = self::get_by_inst_id($inst_id, $semester, $year);
$data = self::get_by_inst_id($inst_id, $semester, $year, $is_student);
$total_num_pages = ceil(sizeof($data) / $items_per_page);
$offset = $items_per_page * ($page_number - 1);
$page = array_slice($data, $offset, $items_per_page);
Expand Down Expand Up @@ -327,6 +358,8 @@ public function get_by_id($play_id=0)
$this->elapsed = $r['elapsed'];
$this->context_id = $r['context_id'];
$this->semester = $r['semester'];
$this->auth = $r['auth'];
$this->environment_data = $r['environment_data'];
return true;
}
}
Expand Down
4 changes: 4 additions & 0 deletions fuel/app/classes/materia/widget/instance.php
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,10 @@ public function duplicate(int $owner_id, string $new_name = null, bool $copy_exi
// update name
if ( ! empty($new_name)) $duplicate->name = $new_name;

// is_embedded and embedded_only should default to false for new instances (since the new instance won't have the play history requisite for is_embedded)
$duplicate->is_embedded = false;
$duplicate->embedded_only = false;

// these values aren't saved to the db - but the frontend will make use of them
$duplicate->clean_name = \Inflector::friendly_title($duplicate->name, '-', true);
$base_url = "{$duplicate->id}/{$duplicate->clean_name}";
Expand Down
Loading
Loading