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 %> +
+ search +
+ +
+
+
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