Commit 00d6edf9 authored by Zac Wood's avatar Zac Wood

Added bulk add feature and fixes

parent 32dff2fd
Pipeline #3471 passed with stages
in 12 minutes and 38 seconds
GEM
remote: https://rubygems.org/
specs:
actioncable (5.1.6)
actionpack (= 5.1.6)
actioncable (5.1.6.1)
actionpack (= 5.1.6.1)
nio4r (~> 2.0)
websocket-driver (~> 0.6.1)
actionmailer (5.1.6)
actionpack (= 5.1.6)
actionview (= 5.1.6)
activejob (= 5.1.6)
actionmailer (5.1.6.1)
actionpack (= 5.1.6.1)
actionview (= 5.1.6.1)
activejob (= 5.1.6.1)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.1.6)
actionview (= 5.1.6)
activesupport (= 5.1.6)
actionpack (5.1.6.1)
actionview (= 5.1.6.1)
activesupport (= 5.1.6.1)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.1.6)
activesupport (= 5.1.6)
actionview (5.1.6.1)
activesupport (= 5.1.6.1)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
activejob (5.1.6)
activesupport (= 5.1.6)
activejob (5.1.6.1)
activesupport (= 5.1.6.1)
globalid (>= 0.3.6)
activemodel (5.1.6)
activesupport (= 5.1.6)
activerecord (5.1.6)
activemodel (= 5.1.6)
activesupport (= 5.1.6)
activemodel (5.1.6.1)
activesupport (= 5.1.6.1)
activerecord (5.1.6.1)
activemodel (= 5.1.6.1)
activesupport (= 5.1.6.1)
arel (~> 8.0)
activesupport (5.1.6)
activesupport (5.1.6.1)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (>= 0.7, < 2)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
apipie-rails (0.5.10)
apipie-rails (0.5.14)
rails (>= 4.1)
arel (8.0.0)
ast (2.4.0)
......@@ -57,81 +57,87 @@ GEM
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
coderay (1.1.2)
concurrent-ruby (1.0.5)
concurrent-ruby (1.1.3)
crass (1.0.4)
erubi (1.7.1)
ffi (1.9.25)
globalid (0.4.1)
activesupport (>= 4.2.0)
httparty (0.16.2)
httparty (0.16.3)
mime-types (~> 3.0)
multi_xml (>= 0.5.2)
i18n (1.0.1)
i18n (1.2.0)
concurrent-ruby (~> 1.0)
icalendar (2.4.1)
icalendar (2.5.2)
ice_cube (~> 0.16)
ice_cube (0.16.3)
jaro_winkler (1.5.1)
jbuilder (2.7.0)
jbuilder (2.8.0)
activesupport (>= 4.2.0)
multi_json (>= 1.2)
listen (3.1.5)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
ruby_dep (~> 1.2)
loofah (2.2.2)
loofah (2.2.3)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.7.0)
mail (2.7.1)
mini_mime (>= 0.1.1)
maruku (0.7.3)
method_source (0.9.0)
mini_mime (1.0.0)
method_source (0.9.2)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2018.0812)
mini_mime (1.0.1)
mini_portile2 (2.3.0)
minitest (5.11.3)
multi_json (1.13.1)
multi_xml (0.6.0)
nio4r (2.3.1)
nokogiri (1.8.3)
nokogiri (1.8.5)
mini_portile2 (~> 2.3.0)
parallel (1.12.1)
parser (2.5.1.2)
parser (2.5.3.0)
ast (~> 2.4.0)
powerpack (0.1.2)
pry (0.11.3)
pry (0.12.2)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-doc (0.13.4)
pry-doc (0.13.5)
pry (~> 0.11)
yard (~> 0.9.11)
public_suffix (3.0.2)
puma (3.11.4)
rack (2.0.5)
public_suffix (3.0.3)
puma (3.12.0)
rack (2.0.6)
rack-cors (1.0.2)
rack-test (1.0.0)
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.1.6)
actioncable (= 5.1.6)
actionmailer (= 5.1.6)
actionpack (= 5.1.6)
actionview (= 5.1.6)
activejob (= 5.1.6)
activemodel (= 5.1.6)
activerecord (= 5.1.6)
activesupport (= 5.1.6)
rails (5.1.6.1)
actioncable (= 5.1.6.1)
actionmailer (= 5.1.6.1)
actionpack (= 5.1.6.1)
actionview (= 5.1.6.1)
activejob (= 5.1.6.1)
activemodel (= 5.1.6.1)
activerecord (= 5.1.6.1)
activesupport (= 5.1.6.1)
bundler (>= 1.3.0)
railties (= 5.1.6)
railties (= 5.1.6.1)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.4)
loofah (~> 2.2, >= 2.2.2)
railties (5.1.6)
actionpack (= 5.1.6)
activesupport (= 5.1.6)
railties (5.1.6.1)
actionpack (= 5.1.6.1)
activesupport (= 5.1.6.1)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rainbow (3.0.0)
rake (12.3.1)
rake (12.3.2)
rb-fsevent (0.10.3)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
......@@ -144,12 +150,12 @@ GEM
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.10.0)
rubyXL (3.3.29)
rubyXL (3.3.31)
nokogiri (>= 1.4.4)
rubyzip (>= 1.1.6)
ruby_dep (1.5.0)
rubyzip (1.2.1)
sass (3.5.7)
rubyzip (1.2.2)
sass (3.7.2)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
......@@ -160,9 +166,9 @@ GEM
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
selenium-webdriver (3.13.0)
selenium-webdriver (3.141.0)
childprocess (~> 0.5)
rubyzip (~> 1.2)
rubyzip (~> 1.2, >= 1.2.2)
spring (2.0.2)
activesupport (>= 4.2)
spring-watcher-listen (2.0.1)
......@@ -176,16 +182,13 @@ GEM
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
thor (0.20.0)
thor (0.20.3)
thread_safe (0.3.6)
tilt (2.0.8)
turbolinks (5.1.1)
turbolinks-source (~> 5.1)
turbolinks-source (5.1.0)
tilt (2.0.9)
tzinfo (1.2.5)
thread_safe (~> 0.1)
unicode-display_width (1.4.0)
web-console (3.6.2)
web-console (3.7.0)
actionview (>= 5.0)
activemodel (>= 5.0)
bindex (>= 0.4.0)
......@@ -193,9 +196,9 @@ GEM
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
xpath (3.1.0)
xpath (3.2.0)
nokogiri (~> 1.8)
yard (0.9.14)
yard (0.9.16)
PLATFORMS
ruby
......@@ -214,7 +217,7 @@ DEPENDENCIES
pry-doc
puma (~> 3.7)
rack-cors
rails (~> 5.1.6)
rails (= 5.1.6.1)
rubocop (~> 0.58.2)
rubyXL
sass-rails (~> 5.0)
......@@ -222,7 +225,6 @@ DEPENDENCIES
spring
spring-watcher-listen (~> 2.0.0)
sqlite3
turbolinks (~> 5)
tzinfo-data
web-console (>= 3.3.0)
......
......@@ -47,156 +47,3 @@ class Cart {
return false;
}
}
// class Cart {
// constructor() {
// this.isOpen = false;
// this._courses = {}; {title, id, sections: {id, crn}}
// const cartData = document.getElementById('cart-data');
// const courses = Array.from(cartData.content.children);
// for (const course of courses) {
// const { id, title } = course.dataset;
// const sections = Array.from(course.children).map(node => ({ ...node.dataset }));
// this._courses[id] = { id, title, sections };
// }
// document.getElementById('course-counter').innerText = Object.keys(this._courses).length;
// this._ids = Array.from(document.getElementById('cart-courses').children).map(e => e.dataset.crn);
// }
// get crns() {
// return Object.keys(this._courses)
// .map(cid => this._courses[cid].sections.map(s => s.crn))
// .reduce((prev, curr) => [...prev, ...curr], []);
// }
// get ids() {
// return Object.keys(this._courses)
// .map(cid => this._courses[cid].sections.map(s => s.id))
// .reduce((prev, curr) => [...prev, ...curr], []);
// }
// toggle() {
// const list = document.getElementById('cart');
// const icon = document.getElementById('schedule-icon');
// if (this.isOpen) {
// list.style.display = 'none';
// icon.style.color = 'black';
// } else {
// list.style.display = 'block';
// icon.style.color = 'green';
// }
// this.isOpen = !this.isOpen;
// }
// addCourse(course) {
// this._courses[course.id] = course;
// const courseList = document.getElementById('cart-courses');
// const courseNode = courseList.querySelector(`#schedule-${course.id}`);
// const newNode = this._constructCourseNode(course);
// if (courseNode !== null) courseList.replaceChild(newNode, courseNode);
// else courseList.appendChild(newNode);
// document.getElementById('course-counter').innerText = Object.keys(this._courses).length;
// fetch(`/sessions/update?section_ids=${this.ids.join(',')}`, { cache: 'no-store' });
// }
// removeCourse(id) {
// const sectionIds = this._courses[id].sections.map(s => s.id);
// for (const sectionId of sectionIds) {
// const sectionCard = document.querySelector(`#section-${sectionId}`);
// sectionCard && sectionCard.classList.remove('selected');
// }
// delete this._courses[id];
// const courseList = document.getElementById('cart-courses');
// const current = courseList.querySelector(`#schedule-${id}`);
// courseList.removeChild(current);
// document.getElementById('course-counter').innerText = Object.keys(this._courses).length;
// fetch(`/sessions/update?section_ids=${this.ids.join(',')}`, { cache: 'no-store' });
// }
// courseContainingSection(id) {
// for (const courseId in this._courses) {
// const course = this._courses[courseId];
// for (const section of course.sections) {
// if (section.id == id) return course;
// }
// }
// return undefined;
// }
// includesSection(id) {
// return !!this.courseContainingSection(id);
// }
// section: { id, crn }
// addSection(section) {
// const course = this._courses[section.cid];
// if (course) {
// course.sections.push(section);
// const courseNode = document.getElementById(`schedule-${course.id}`);
// const crnList = courseNode.querySelector('.crns');
// crnList.innerText = course.sections.map(s => `#${s.crn}`);
// fetch(`/sessions/update?section_ids=${this.ids.join(',')}`, { cache: 'no-store' });
// } else {
// const courseCard = document.getElementById(`course-${section.cid}`);
// const title = courseCard.querySelector('.title').innerText;
// this.addCourse({ title, id: section.cid, sections: [section] });
// }
// }
// removeSection(section) {
// const course = this.courseContainingSection(section.id);
// course.sections = course.sections.filter(s => s.id !== section.id);
// const schedule = document.querySelector('#cart-courses');
// const courseNode = schedule.querySelector(`#schedule-${course.id}`);
// const crnList = courseNode.querySelector('.crns');
// if (course.sections.length === 0) {
// this.removeCourse(section.cid);
// } else {
// crnList.innerText = course.sections.map(s => `#${s.crn}`);
// }
// fetch(`/sessions/update?section_ids=${this.ids.join(',')}`, { cache: 'no-store' });
// }
// async downloadIcs() {
// const cal = await fetch(`/api/schedules?crns=${this.crns.join(',')}`);
// const text = await cal.text();
// var blob = new Blob([text], { type: 'text/calendar;charset=utf-8' });
// saveAs(blob, 'test.ics');
// }
// async addToSystemCalendar() {
// const url = `webcal:${window.location.hostname}/api/schedule?crns=${this.crns.join(',')}`;
// window.open(url, '_self');
// }
// _constructCourseNode(course) {
// let html = `<li id="schedule-${course.id}" class="list-group-item schedule-section-card" onclick="removeCourse(${course.id})">`;
// html += `<div style="display: flex; justify-content: space-between;">`;
// html += `<b style="min-width: 15%">${course.title}</b>`;
// html += `<span class="crns" style="color: gray; font-size: 10pt;">`;
// html += course.sections.map(s => `#${s.crn}`).join(', ');
// html += `</span>`;
// html += `</div>`;
// html += `</li>`;
// return elementFromString(html);
// }
// }
// const removeCourse = id => {
// this.cart.removeCourse(id);
// };
#calendar {
background-color: white;
padding: 16px;
margin-bottom: 8px;
}
.section-item.selected {
......
class SearchController < ApplicationController
def index
# sorry zach
results = SearchHelper::GenericItem.fetchall(String.new(params[:query]), semester: @semester).group_by(&:type)
@instructors = results[:instructor]
@courses = results[:course]
# results = search(params[:query])
@instructors = results[:instructor]&.map(&:data)
@courses = results[:course]&.map(&:data)
end
# cases
# math 113 - [a-zA-Z]{3,} [1-9]{3}
end
......@@ -16,11 +16,20 @@ class SessionsController < ApplicationController
@cart << section_id
end
puts @cart.to_json
cookies[:cart] = @cart.to_json
render json: @cart.to_json
end
def add_bulk
crns = params[:crns].split(',')
crns.each { |crn|
section_id = CourseSection.find_by_crn(crn).id.to_s
@cart << section_id unless @cart.include?(section_id)
}
cookies[:cart] = @cart.to_json
redirect_to schedule_path
end
private
def update_cookie(sym)
......
<h1>Welcome to Schedules!</h1>
<p>Schedules is a website designed by Mason SRCT designed to help students explore the GMU Catalog.</p>
Search for either professors or courses using the search bar above.
<p>Schedules is a website built by <a href="https://srct.gmu.edu">Mason SRCT</a> designed to help students explore the GMU Catalog.</p>
Search for either courses or professors using the search bar above.
<br/>
<p></p>
<h3>Quick add</h3>
<p>Want to quickly generate a calendar populated with your semester's classes? Enter the CRNs in a comma separated list below.</p>
<form action="/sessions/add_bulk" class="form">
<div class="input-group">
<input
id="crns"
name="crns"
type="text"
class="form-control"
placeholder="12345,54321,..."
aria-describedby="basic-addon2"
autocomplete="off"
>
<div class="input-group-append">
<button type="submit" class="btn btn-primary" type="button">
Populate Calendar
</button>
</div>
</div>
</form>
......@@ -7,10 +7,32 @@
<%= javascript_include_tag 'fullcalendar.min'%>
<%= stylesheet_link_tag 'fullcalendar.min' %>
<button id="open-modal-btn" type="button" class="btn btn-primary" data-toggle="modal" data-target="#exportModal">
Generate Schedule
</button>
<div id="calendar"></div>
<h3>Quick add</h3>
<p>Populate your calendar quickly by entering a comma separated list of CRNs.</p>
<form action="/sessions/add_bulk" class="form">
<div class="input-group">
<input
id="crns"
name="crns"
type="text"
class="form-control"
placeholder="12345,54321,..."
aria-describedby="basic-addon2"
autocomplete="off"
>
<div class="input-group-append">
<button type="submit" class="btn btn-primary" type="button">
Populate Calendar
</button>
</div>
</div>
</form>
<template id="events" data-events="<%= @events.to_json %>"></template>
......
<% unless @instructors.nil? %>
<h2>Instructors</h2>
<div class="row">
<% @instructors.map(&:data).each do |instructor| %>
<% @instructors.each do |instructor| %>
<div class="col"><%= render partial: 'shared/instructor', object: instructor %></div>
<% end %>
</div>
......@@ -10,7 +10,7 @@
<% unless @courses.nil? %>
<h2>Courses</h2>
<% @courses.map(&:data).each do |course| %>
<% @courses.each do |course| %>
<div class="col"><%= render partial: 'shared/course', object: course %></div>
<% end %>
<% end %>
......
......@@ -42,7 +42,7 @@
name="query"
type="text"
class="form-control"
placeholder="Search by CRN, course, professor..."
placeholder="Search course or professor..."
aria-describedby="basic-addon2"
autocomplete="off"
>
......
......@@ -3,6 +3,7 @@ Rails.application.routes.draw do
get 'search', to: 'search#index'
get 'sessions/update', as: 'update_session'
get 'sessions/cart'
get 'sessions/add_bulk'
resources :courses, only: [:show]
resources :instructors, only: [:index, :show]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment