Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SRCT
schedules
Commits
7361194d
Commit
7361194d
authored
Dec 17, 2018
by
Zac Wood
Browse files
The Webpackening
parent
758c4ec2
Pipeline
#3510
failed with stages
in 2 minutes and 2 seconds
Changes
34
Pipelines
3
Hide whitespace changes
Inline
Side-by-side
schedules/.babelrc
0 → 100644
View file @
7361194d
{
"presets": [
["env", {
"modules": false,
"targets": {
"browsers": "> 1%",
"uglify": true
},
"useBuiltIns": true
}]
],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
["transform-class-properties", { "spec": true }]
]
}
schedules/.gitignore
View file @
7361194d
...
...
@@ -21,3 +21,8 @@
/yarn-error.log
.byebug_history
/public/packs
/public/packs-test
/node_modules
yarn-debug.log*
.yarn-integrity
schedules/.postcssrc.yml
0 → 100644
View file @
7361194d
plugins
:
postcss-import
:
{}
postcss-cssnext
:
{}
schedules/Gemfile
View file @
7361194d
...
...
@@ -19,6 +19,8 @@ gem 'jbuilder', '~> 2.5'
gem
'uglifier'
gem
'webpacker'
,
'~> 3.5'
# Use Redis adapter to run Action Cable in production
# gem 'redis', '~> 4.0'
# Use ActiveModel has_secure_password
...
...
schedules/Gemfile.lock
View file @
7361194d
...
...
@@ -57,7 +57,7 @@ GEM
childprocess (0.9.0)
ffi (~> 1.0, >= 1.0.11)
coderay (1.1.2)
concurrent-ruby (1.1.
3
)
concurrent-ruby (1.1.
4
)
crass (1.0.4)
erubi (1.7.1)
execjs (2.7.0)
...
...
@@ -101,7 +101,6 @@ GEM
parallel (1.12.1)
parser (2.5.3.0)
ast (~> 2.4.0)
pg (1.1.3)
powerpack (0.1.2)
pry (0.12.2)
coderay (~> 1.1.0)
...
...
@@ -113,6 +112,8 @@ GEM
puma (3.12.0)
rack (2.0.6)
rack-cors (1.0.2)
rack-proxy (0.6.5)
rack
rack-test (1.1.0)
rack (>= 1.0, < 3)
rails (5.1.6.1)
...
...
@@ -197,6 +198,10 @@ GEM
activemodel (>= 5.0)
bindex (>= 0.4.0)
railties (>= 5.0)
webpacker (3.5.5)
activesupport (>= 4.2)
rack-proxy (>= 0.6.1)
railties (>= 4.2)
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.3)
...
...
@@ -217,7 +222,6 @@ DEPENDENCIES
listen (>= 3.0.5, < 3.2)
maruku
nokogiri
pg
pry
pry-doc
puma (~> 3.7)
...
...
@@ -233,6 +237,7 @@ DEPENDENCIES
tzinfo-data
uglifier
web-console (>= 3.3.0)
webpacker (~> 3.5)
BUNDLED WITH
1.16.3
schedules/app/assets/javascripts/courses.js
deleted
100644 → 0
View file @
758c4ec2
/**
* Either adds or removes a section from the cart depending on
* if it is currently in the cart.
*/
const
addOrRemoveFromCart
=
async
(
event
,
sectionNode
)
=>
{
event
&&
event
.
stopPropagation
();
const
section
=
{
...
sectionNode
.
dataset
};
await
this
.
cart
.
addSection
(
section
);
if
(
this
.
cart
.
includesSection
(
section
))
{
sectionNode
.
classList
.
add
(
'
selected
'
);
}
else
{
sectionNode
.
classList
.
remove
(
'
selected
'
);
}
};
const
initListeners
=
()
=>
{
const
items
=
Array
.
from
(
document
.
querySelectorAll
(
'
.section-item
'
));
items
.
forEach
(
item
=>
(
item
.
onclick
=
e
=>
addOrRemoveFromCart
(
e
,
item
)));
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
initListeners
);
schedules/app/assets/javascripts/home.js
deleted
100644 → 0
View file @
758c4ec2
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
schedules/app/assets/javascripts/instructors.js
deleted
100644 → 0
View file @
758c4ec2
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
schedules/app/assets/javascripts/jsconfig.json
deleted
100644 → 0
View file @
758c4ec2
{
"compilerOptions"
:
{
"lib"
:
[
"es2015"
,
"dom"
]
}
}
schedules/app/assets/javascripts/sections.js
deleted
100644 → 0
View file @
758c4ec2
schedules/app/assets/javascripts/sessions.js
deleted
100644 → 0
View file @
758c4ec2
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
schedules/app/controllers/schedules_controller.rb
View file @
7361194d
...
...
@@ -21,7 +21,7 @@ class SchedulesController < ApplicationController
@all
=
params
[
:crns
].
split
(
','
).
map
{
|
crn
|
CourseSection
.
latest_by_crn
(
crn
)
}
@all
.
reject!
{
|
s
|
s
.
nil?
}
@all
.
reject!
(
&
:
nil?
)
@without_online
=
@all
.
reject
{
|
s
|
s
.
start_time
==
"TBA"
||
s
.
end_time
==
"TBA"
}
...
...
schedules/app/
assets/
javascripts/application.js
→
schedules/app/javascript
/pack
s/application.js
View file @
7361194d
//= require FileSaver
//= require cart
/* eslint no-console:0 */
// This file is automatically compiled by Webpack, along with any other files
// present in this directory. You're encouraged to place your actual application logic in
// a relevant structure within app/javascript and only use these pack files to reference
// that code so it'll be compiled.
//
// To reference this file, add <%= javascript_pack_tag 'application' %> to the appropriate
// layout file, like app/views/layouts/application.html.erb
import
'
@babel/polyfill
'
;
import
'
url-polyfill
'
;
const
elementFromString
=
string
=>
{
const
html
=
new
DOMParser
().
parseFromString
(
string
,
'
text/html
'
);
...
...
@@ -7,7 +16,6 @@ const elementFromString = string => {
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
this
.
cart
=
new
Cart
();
initGlobalListeners
();
});
...
...
schedules/app/
assets/
javascripts/schedules.js
→
schedules/app/javascript
/pack
s/schedules.js
View file @
7361194d
import
Cart
from
'
src/cart
'
;
import
{
saveAs
}
from
'
file-saver
'
;
import
html2canvas
from
'
html2canvas
'
;
import
$
from
'
jquery
'
;
import
'
fullcalendar
'
;
import
'
moment
'
;
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
eventsTemplate
=
document
.
querySelector
(
'
#events
'
);
if
(
eventsTemplate
)
{
...
...
@@ -13,7 +20,6 @@ document.addEventListener('DOMContentLoaded', () => {
allDaySlot
:
false
,
});
}
initListeners
();
});
...
...
@@ -22,7 +28,7 @@ const renderEvents = (start, end, timezone, callback) => {
};
const
remove
=
async
item
=>
{
await
window
.
c
art
.
toggleSection
({
...
item
.
dataset
});
await
C
art
.
toggleSection
({
...
item
.
dataset
});
location
.
reload
(
true
);
};
...
...
@@ -31,22 +37,22 @@ const remove = async item => {
* and sets the link in the modal to it.
*/
const
setUrlInModal
=
()
=>
{
document
.
getElementById
(
'
calendar-link
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
window
.
c
art
.
_courses
.
join
(
'
,
'
)}
`
;
document
.
getElementById
(
'
calendar-link
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
C
art
.
_courses
.
join
(
'
,
'
)}
`
;
};
const
downloadIcs
=
async
()
=>
{
const
response
=
await
fetch
(
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
window
.
c
art
.
_courses
.
join
(
'
,
'
)}
`
);
const
response
=
await
fetch
(
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
C
art
.
_courses
.
join
(
'
,
'
)}
`
);
const
text
=
await
response
.
text
();
const
blob
=
new
Blob
([
text
],
{
type
:
'
text/calendar;charset=utf-8
'
});
saveAs
(
blob
,
'
GMU Schedule.ics
'
);
};
const
addToSystemCalendar
=
()
=>
{
window
.
open
(
`webcal://
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
window
.
c
art
.
_courses
.
join
(
'
,
'
)}
`
);
window
.
open
(
`webcal://
${
window
.
location
.
hostname
}
/api/schedules?crns=
${
C
art
.
_courses
.
join
(
'
,
'
)}
`
);
};
const
saveImage
=
()
=>
{
html2canvas
(
document
.
querySelector
(
"
#calendar
"
)).
then
(
canvas
=>
{
html2canvas
(
document
.
querySelector
(
'
#calendar
'
)).
then
(
canvas
=>
{
canvas
.
toBlob
(
blob
=>
{
saveAs
(
blob
,
'
GMU Schedule.png
'
);
});
...
...
@@ -62,5 +68,24 @@ const initListeners = () => {
document
.
getElementById
(
'
add-to-system
'
).
onclick
=
addToSystemCalendar
;
document
.
getElementById
(
'
save-image
'
).
onclick
=
saveImage
;
document
.
getElementById
(
'
share-url
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/schedule/view?crns=
${
window
.
c
art
.
_courses
.
join
(
'
,
'
)}
`
;
document
.
getElementById
(
'
share-url
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/schedule/view?crns=
${
C
art
.
_courses
.
join
(
'
,
'
)}
`
;
};
if
(
!
HTMLCanvasElement
.
prototype
.
toBlob
)
{
Object
.
defineProperty
(
HTMLCanvasElement
.
prototype
,
'
toBlob
'
,
{
value
:
function
(
callback
,
type
,
quality
)
{
var
canvas
=
this
;
setTimeout
(
function
()
{
var
binStr
=
atob
(
canvas
.
toDataURL
(
type
,
quality
).
split
(
'
,
'
)[
1
]),
len
=
binStr
.
length
,
arr
=
new
Uint8Array
(
len
);
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
arr
[
i
]
=
binStr
.
charCodeAt
(
i
);
}
callback
(
new
Blob
([
arr
],
{
type
:
type
||
'
image/png
'
}));
});
},
});
}
schedules/app/
assets/
javascripts/schedules_view.js
→
schedules/app/javascript
/pack
s/schedules_view.js
View file @
7361194d
import
Cart
from
'
src/cart
'
;
import
{
saveAs
}
from
'
file-saver
'
;
import
html2canvas
from
'
html2canvas
'
;
import
$
from
'
jquery
'
;
import
'
fullcalendar
'
;
import
'
moment
'
;
import
'
url-polyfill
'
;
const
params
=
new
URLSearchParams
(
document
.
location
.
search
);
const
crns
=
params
.
get
(
'
crns
'
);
...
...
@@ -24,7 +32,6 @@ const renderEvents = (start, end, timezone, callback) => {
callback
(
window
.
events
);
};
/**
* Generates a URL for the current sections in the schedule
* and sets the link in the modal to it.
...
...
@@ -45,7 +52,7 @@ const addToSystemCalendar = () => {
};
const
saveImage
=
()
=>
{
html2canvas
(
document
.
querySelector
(
"
#calendar
"
)).
then
(
canvas
=>
{
html2canvas
(
document
.
querySelector
(
'
#calendar
'
)).
then
(
canvas
=>
{
canvas
.
toBlob
(
blob
=>
{
saveAs
(
blob
,
'
GMU Schedule.png
'
);
});
...
...
@@ -56,6 +63,24 @@ const initListeners = () => {
document
.
getElementById
(
'
open-modal-btn
'
).
onclick
=
setUrlInModal
;
document
.
getElementById
(
'
download-ics
'
).
onclick
=
downloadIcs
;
document
.
getElementById
(
'
add-to-system
'
).
onclick
=
addToSystemCalendar
;
document
.
getElementById
(
'
share-url
'
).
innerText
=
`
${
window
.
location
.
protocol
}
//
${
window
.
location
.
hostname
}
/schedule/view?crns=
${
crns
}
`
;
document
.
getElementById
(
'
save-image
'
).
onclick
=
saveImage
;
};
if
(
!
HTMLCanvasElement
.
prototype
.
toBlob
)
{
Object
.
defineProperty
(
HTMLCanvasElement
.
prototype
,
'
toBlob
'
,
{
value
:
function
(
callback
,
type
,
quality
)
{
var
canvas
=
this
;
setTimeout
(
function
()
{
var
binStr
=
atob
(
canvas
.
toDataURL
(
type
,
quality
).
split
(
'
,
'
)[
1
]),
len
=
binStr
.
length
,
arr
=
new
Uint8Array
(
len
);
for
(
var
i
=
0
;
i
<
len
;
i
++
)
{
arr
[
i
]
=
binStr
.
charCodeAt
(
i
);
}
callback
(
new
Blob
([
arr
],
{
type
:
type
||
'
image/png
'
}));
});
},
});
}
schedules/app/
assets/
javascripts/search.js
→
schedules/app/javascript
/pack
s/search.js
View file @
7361194d
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.
import
Cart
from
'
src/cart
'
;
/**
* Either adds or removes a section from the cart depending on
...
...
@@ -9,10 +10,10 @@ const addOrRemoveFromCart = async (event, sectionNode) => {
event
&&
event
.
stopPropagation
();
const
section
=
{
...
sectionNode
.
dataset
};
await
this
.
c
art
.
toggleSection
(
section
);
await
C
art
.
toggleSection
(
section
);
const
icon
=
$
(
sectionNode
.
querySelector
(
'
.add-remove-btn #icon
'
));
const
text
=
sectionNode
.
querySelector
(
'
.add-remove-btn .text
'
);
if
(
this
.
c
art
.
includesSection
(
section
))
{
if
(
C
art
.
includesSection
(
section
))
{
icon
.
addClass
(
'
fa-minus
'
).
removeClass
(
'
fa-plus
'
);
text
.
innerText
=
'
Remove
'
;
}
else
{
...
...
schedules/app/
assets/
javascript
s
/cart.js
→
schedules/app/javascript
/src
/cart.js
View file @
7361194d
//import '@babel/polyfill';
class
Cart
{
constructor
()
{
this
.
isOpen
=
false
;
...
...
@@ -9,6 +11,13 @@ class Cart {
}
}
_parseData
()
{
const
cartData
=
document
.
getElementById
(
'
cart-data
'
);
if
(
cartData
)
{
this
.
_courses
=
JSON
.
parse
(
cartData
.
dataset
.
cart
);
}
}
toggle
()
{
const
list
=
document
.
getElementById
(
'
cart
'
);
const
icon
=
document
.
getElementById
(
'
schedule-icon
'
);
...
...
@@ -33,7 +42,10 @@ class Cart {
}
async
toggleSection
(
section
)
{
const
resp
=
await
fetch
(
`/sessions/cart?&crn=
${
section
.
crn
}
`
,
{
cache
:
'
no-store
'
});
const
resp
=
await
fetch
(
`/sessions/cart?&crn=
${
section
.
crn
}
`
,
{
cache
:
'
no-store
'
,
credentials
:
'
same-origin
'
});
const
json
=
await
resp
.
json
();
this
.
courses
=
json
;
}
...
...
@@ -47,3 +59,10 @@ class Cart {
return
false
;
}
}
const
cart
=
new
Cart
();
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
cart
.
_parseData
());
export
default
cart
;
schedules/app/views/courses/show.html.erb
View file @
7361194d
...
...
@@ -29,5 +29,5 @@
</div>
<%=
javascript_
include
_tag
'search'
%>
<%=
javascript_
pack
_tag
'search'
%>
<%=
stylesheet_link_tag
'search'
%>
schedules/app/views/instructors/show.html.erb
View file @
7361194d
...
...
@@ -21,5 +21,5 @@
</div>
</div>
<%=
javascript_
include
_tag
'search'
%>
<%=
javascript_
pack
_tag
'search'
%>
<%=
stylesheet_link_tag
'search'
%>
schedules/app/views/layouts/application.html.erb
View file @
7361194d
...
...
@@ -6,11 +6,12 @@
<meta
name=
"viewport"
content=
"width=device-width, initial-scale=1.0"
>
<%=
javascript_include_tag
'masonstrap.min'
%>
<%=
javascript_include_tag
'application'
%>
<%=
stylesheet_link_tag
'masonstrap.min'
%>
<%=
stylesheet_link_tag
'application'
%>
<%=
javascript_pack_tag
'application'
%>
<!-- FB/Opengraph tags -->
<meta
property=
"og:url"
content=
"https://schedules.gmu.edu/"
>
<meta
property=
"og:type"
content=
"website"
>
...
...
Prev
1
2
Next
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment