diff --git a/Gemfile b/Gemfile
index 45367d901..c4c4be3ea 100644
--- a/Gemfile
+++ b/Gemfile
@@ -49,7 +49,7 @@ gem 'rake', '>=10.3.2'
gem 'populator', '>=1.0.0'
# To communicate with MySQL database
-gem 'mysql2', '~>0.5'
+gem 'mysql2', '=0.5.4'
# Development server
gem 'thin'
diff --git a/Gemfile.lock b/Gemfile.lock
index 37120e5a4..ea382c020 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -231,7 +231,7 @@ GEM
momentjs-rails (2.15.1)
railties (>= 3.1)
multi_xml (0.6.0)
- mysql2 (0.5.5)
+ mysql2 (0.5.4)
net-http (0.4.0)
uri
net-imap (0.4.9)
@@ -470,6 +470,7 @@ PLATFORMS
arm64-darwin-21
arm64-darwin-22
arm64-darwin-23
+ arm64-darwin-24
x86_64-darwin-19
x86_64-darwin-20
x86_64-darwin-21
@@ -509,7 +510,7 @@ DEPENDENCIES
mini_racer (~> 0.6.3)
moment_timezone-rails
momentjs-rails (>= 2.9.0)
- mysql2 (~> 0.5)
+ mysql2 (= 0.5.4)
net-http
net-ldap
newrelic_rpm
diff --git a/app/assets/javascripts/gradesheet.js.erb b/app/assets/javascripts/gradesheet.js.erb
index 8efac3891..37e501a55 100755
--- a/app/assets/javascripts/gradesheet.js.erb
+++ b/app/assets/javascripts/gradesheet.js.erb
@@ -118,10 +118,9 @@ jQuery(function() {
// main score table
var oTable = jQuery("#grades").dataTable({
'data' : table_data,
- 'sDom' : '<"tools"f>t', // '<"tools"fC>t', for individual problem column hide/show
+ 'sDom' : 't', // '<"tools"fC>t', for individual problem column hide/show
'bInfo': false,
'bPaginate': true,
- 'oLanguage': { "sSearch": "" },
'iTabIndex': -1,
'iDisplayLength': rows_on_display,
'iDisplayStart': 0,
@@ -148,6 +147,19 @@ jQuery(function() {
"aaSorting": [[ email_col, 'asc' ],[lec_sec_col, 'asc']]
}).fnSetFilteringDelay();
+ $('#filter').on('keyup', function() {
+ oTable.fnFilter(this.value);
+ });
+
+ $('#filter').on('keydown', function(event) {
+ if (event.keyCode === 13) { // return
+ asap(function() { jQuery(focusser).focus(); });
+ } else if (event.keyCode === 27) { // esc
+ event.preventDefault();
+ jQuery(this).val("");
+ }
+ });
+
// add sorting icons to table headings
function add_icons(selector) {
let icons = $icon_template.clone();
@@ -187,10 +199,6 @@ jQuery(function() {
}
})
- // placeholder text in Search field
- jQuery("#grades_filter input").attr("placeholder", "Search");
-
-
// get enclosing editor from inside of it
function get_enclosing_editor(el) {
return jQuery(el).closest('td.edit');
@@ -501,18 +509,6 @@ jQuery(function() {
$(event.target).data('changed', !$(event.target).data('changed'));
});
-
- jQuery("#grades_filter input").keydown(function(event){
- if (event.keyCode === 13) { // return
- asap(function() { jQuery(focusser).focus(); });
- } else if (event.keyCode === 27) { // esc
- event.preventDefault();
- jQuery(this).val("");
- }
- });
-
- jQuery('#grades_filter input').focus()
-
jQuery(document).click(function(event) {
close_current_editor_on_blur(event);
close_current_popover_on_blur(event);
diff --git a/app/assets/stylesheets/gradesheet.css.scss b/app/assets/stylesheets/gradesheet.css.scss
index 4236243ce..508369866 100755
--- a/app/assets/stylesheets/gradesheet.css.scss
+++ b/app/assets/stylesheets/gradesheet.css.scss
@@ -15,6 +15,17 @@ td.focus {
margin-bottom: 20px;
}
+div.filter_container.search-student-bar {
+ display: flex;
+ flex-direction: row;
+ align-items: center;
+}
+
+div.filter_container.search-student-bar input {
+ padding-left: 8px;
+ height: 3rem;
+}
+
#grades_wrapper .tools div {
display: inline;
margin-right: 7px;
diff --git a/app/views/assessments/viewGradesheet.html.erb b/app/views/assessments/viewGradesheet.html.erb
index 68738885a..adbe29450 100755
--- a/app/views/assessments/viewGradesheet.html.erb
+++ b/app/views/assessments/viewGradesheet.html.erb
@@ -280,6 +280,13 @@ Interaction between gradesheet and annotations
<% end %>
+
+
diff --git a/db/schema.rb b/db/schema.rb
index b212ea0a3..7e5d7a428 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,13 +10,13 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2024_04_06_174050) do
+ActiveRecord::Schema.define(version: 2025_04_26_203028) do
create_table "active_storage_attachments", force: :cascade do |t|
t.string "name", null: false
t.string "record_type", null: false
- t.bigint "record_id", null: false
- t.bigint "blob_id", null: false
+ t.integer "record_id", null: false
+ t.integer "blob_id", null: false
t.datetime "created_at", null: false
t.index ["blob_id"], name: "index_active_storage_attachments_on_blob_id"
t.index ["record_type", "record_id", "name", "blob_id"], name: "index_active_storage_attachments_uniqueness", unique: true
@@ -27,7 +27,7 @@
t.string "filename", null: false
t.string "content_type"
t.text "metadata"
- t.bigint "byte_size", null: false
+ t.integer "byte_size", null: false
t.string "checksum", null: false
t.datetime "created_at", null: false
t.string "service_name", null: false
@@ -35,7 +35,7 @@
end
create_table "active_storage_variant_records", force: :cascade do |t|
- t.bigint "blob_id", null: false
+ t.integer "blob_id", null: false
t.string "variation_digest", null: false
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
end
@@ -54,6 +54,8 @@
t.string "coordinate"
t.boolean "shared_comment", default: false
t.boolean "global_comment", default: false
+ t.integer "rubric_item_id"
+ t.index ["rubric_item_id"], name: "index_annotations_on_rubric_item_id"
end
create_table "announcements", force: :cascade do |t|
@@ -130,7 +132,7 @@
t.integer "course_id"
t.integer "assessment_id"
t.string "category_name", default: "General"
- t.datetime "release_at", default: -> { "CURRENT_TIMESTAMP" }
+ t.datetime "release_at"
t.string "slug"
t.index ["assessment_id"], name: "index_attachments_on_assessment_id"
t.index ["slug"], name: "index_attachments_on_slug", unique: true
@@ -194,14 +196,14 @@
t.boolean "infinite", default: false, null: false
end
- create_table "friendly_id_slugs", charset: "utf8mb3", force: :cascade do |t|
+ create_table "friendly_id_slugs", force: :cascade do |t|
t.string "slug", null: false
t.integer "sluggable_id", null: false
t.string "sluggable_type", limit: 50
t.string "scope"
t.datetime "created_at"
- t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true, length: { slug: 70, scope: 70 }
- t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type", length: { slug: 140 }
+ t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true
+ t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type"
t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id"
end
@@ -225,8 +227,8 @@
t.string "context_id"
t.integer "course_id"
t.datetime "last_synced"
- t.datetime "created_at", null: false
- t.datetime "updated_at", null: false
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
t.string "membership_url"
t.string "platform"
t.boolean "auto_sync", default: false
@@ -319,6 +321,28 @@
t.integer "course_id"
end
+ create_table "rubric_item_assignments", force: :cascade do |t|
+ t.integer "rubric_item_id", null: false
+ t.integer "submission_id", null: false
+ t.boolean "assigned", default: false
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["rubric_item_id", "submission_id"], name: "index_ria_on_rubric_item_id_and_submission_id", unique: true
+ t.index ["rubric_item_id"], name: "index_rubric_item_assignments_on_rubric_item_id"
+ t.index ["submission_id"], name: "index_rubric_item_assignments_on_submission_id"
+ end
+
+ create_table "rubric_items", force: :cascade do |t|
+ t.integer "problem_id", null: false
+ t.string "description", null: false
+ t.float "points", null: false
+ t.integer "order", null: false
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["problem_id", "order"], name: "index_rubric_items_on_problem_id_and_order", unique: true
+ t.index ["problem_id"], name: "index_rubric_items_on_problem_id"
+ end
+
create_table "scheduler", force: :cascade do |t|
t.string "action"
t.datetime "next"
@@ -326,7 +350,7 @@
t.integer "course_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.datetime "until", default: -> { "CURRENT_TIMESTAMP" }
+ t.datetime "until"
t.boolean "disabled", default: false
end
@@ -338,15 +362,15 @@
create_table "scoreboards", force: :cascade do |t|
t.integer "assessment_id"
- t.text "banner"
- t.text "colspec"
+ t.text "banner", limit: 65535
+ t.text "colspec", limit: 65535
t.boolean "include_instructors", default: false
end
create_table "scores", force: :cascade do |t|
t.integer "submission_id"
t.float "score"
- t.text "feedback", size: :medium
+ t.text "feedback", limit: 16777215
t.integer "problem_id"
t.datetime "created_at"
t.datetime "updated_at"
@@ -372,7 +396,7 @@
t.string "submitter_ip", limit: 40
t.integer "tweak_id"
t.boolean "ignored", default: false, null: false
- t.string "dave"
+ t.string "dave", limit: 255
t.text "embedded_quiz_form_answer"
t.integer "submitted_by_app_id"
t.string "group_key", default: ""
@@ -437,4 +461,12 @@
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
+ add_foreign_key "annotations", "rubric_items"
+ add_foreign_key "github_integrations", "users"
+ add_foreign_key "oauth_access_grants", "oauth_applications", column: "application_id"
+ add_foreign_key "oauth_access_tokens", "oauth_applications", column: "application_id"
+ add_foreign_key "oauth_device_flow_requests", "oauth_applications", column: "application_id"
+ add_foreign_key "rubric_item_assignments", "rubric_items"
+ add_foreign_key "rubric_item_assignments", "submissions"
+ add_foreign_key "rubric_items", "problems"
end
diff --git a/libsqlite3.dylib b/libsqlite3.dylib
new file mode 100755
index 000000000..41e88f962
Binary files /dev/null and b/libsqlite3.dylib differ