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
c9553734
Commit
c9553734
authored
Sep 09, 2018
by
Zac Wood
Browse files
Added modal export box which contains multiple options for exporting
parent
df064eb3
Pipeline
#2866
passed with stage
in 2 minutes and 23 seconds
Changes
6
Pipelines
1
Show whitespace changes
Inline
Side-by-side
schedules_web/package.json
View file @
c9553734
...
...
@@ -4,7 +4,7 @@
"main"
:
"index.js"
,
"scripts"
:
{
"build"
:
"webpack --config webpack.prod.js --debug --progress"
,
"start"
:
"webpack-dev-server --config webpack.dev.js --inline
--open
"
,
"start"
:
"webpack-dev-server --config webpack.dev.js --inline"
,
"prod"
:
"node app.js"
},
"license"
:
"Apache"
,
...
...
schedules_web/src/components/ExportModal.tsx
View file @
c9553734
import
*
as
React
from
'
react
'
;
import
{
Button
,
Modal
,
ModalHeader
,
ModalBody
,
ModalFooter
}
from
'
reactstrap
'
;
import
{
downloadFile
}
from
'
../util/utilities
'
;
interface
Props
{
isModalOpen
:
boolean
;
toggleModal
:
()
=>
void
;
calendarUrl
:
()
=>
string
;
openCalendarAsWebcal
:
()
=>
void
;
downloadIcs
:
()
=>
Promise
<
void
>
;
}
class
ExportModal
extends
React
.
Component
<
Props
,
{}
>
{
render
()
{
const
{
isModalOpen
,
toggleModal
}
=
this
.
props
;
const
{
isModalOpen
,
toggleModal
,
calendarUrl
,
openCalendarAsWebcal
,
downloadIcs
}
=
this
.
props
;
return
(
<
Modal
isOpen
=
{
isModalOpen
}
toggle
=
{
toggleModal
}
>
<
ModalHeader
toggle
=
{
toggleModal
}
>
Your calendar has been generated!
</
ModalHeader
>
<
ModalBody
>
Here are instructions for adding you calendar to a bunch of different calendar managers.
<
h5
>
Apple Calendar
</
h5
>
To add your schedule to Apple Calendar, click the "Add to calendar" button below. If you are on a
device running macOS or iOS, this will open a dialogue which will walk you through adding the
calendar.
<
hr
/>
<
h5
>
Google Calendar
</
h5
>
<
strong
>
On desktop:
</
strong
>
<
br
/>
Open your
<
a
href
=
"https://calendar.google.com/"
>
Google Calendar
</
a
>
. Click the "Settings" button in
the top right, and then click the Settings tab. In the menu on the left, click "Add calendar" and
"From URL". Now, paste the following link inside the text box:
<
br
/>
<
code
>
{
calendarUrl
()
}
</
code
>
<
br
/>
<
strong
>
On mobile (Android only):
</
strong
>
<
br
/>
Click the "Download calendar file" button. This will download the calendar file which you may then
open and add to your calendar.
<
hr
/>
<
h5
>
.ics file
</
h5
>
To download a .ics file containing your schedule, click the "Download calendar file" button below.
</
ModalBody
>
<
ModalFooter
>
<
Button
color
=
"secondary"
onClick
=
{
toggleModal
}
>
<
Button
color
=
"secondary"
onClick
=
{
downloadIcs
}
>
Download calendar file
</
Button
>
<
Button
color
=
"primary"
onClick
=
{
toggleMod
al
}
>
<
Button
color
=
"primary"
onClick
=
{
openCalendarAsWebc
al
}
>
Add to calendar
</
Button
>
{
'
'
}
</
ModalFooter
>
...
...
schedules_web/src/components/ScheduleBadge.tsx
View file @
c9553734
...
...
@@ -6,8 +6,10 @@ import ExportModal from './ExportModal';
interface
ScheduleBadgeProps
{
schedule
:
CourseSection
[];
generateCalendar
:
(
schedule
:
CourseSection
[])
=>
Promise
<
void
>
;
removeCourseSection
:
(
courseSection
:
CourseSection
)
=>
void
;
generateCalendarUrl
:
()
=>
string
;
openCalendarAsWebcal
:
()
=>
void
;
downloadIcs
:
()
=>
Promise
<
void
>
;
}
interface
State
{
...
...
@@ -28,7 +30,7 @@ class ScheduleBadge extends React.Component<ScheduleBadgeProps, State> {
toggleModal
=
()
=>
this
.
setState
({
isModalOpen
:
!
this
.
state
.
isModalOpen
});
render
()
{
const
{
schedule
,
removeCourseSection
,
generateCalendar
}
=
this
.
props
;
const
{
schedule
,
removeCourseSection
,
generateCalendar
Url
,
openCalendarAsWebcal
,
downloadIcs
}
=
this
.
props
;
return
(
<
div
>
<
Row
className
=
"justify-content-end"
>
...
...
@@ -73,7 +75,13 @@ class ScheduleBadge extends React.Component<ScheduleBadgeProps, State> {
</
CardBody
>
</
Card
>
</
Collapse
>
<
ExportModal
isModalOpen
=
{
this
.
state
.
isModalOpen
}
toggleModal
=
{
this
.
toggleModal
}
/>
<
ExportModal
isModalOpen
=
{
this
.
state
.
isModalOpen
}
toggleModal
=
{
this
.
toggleModal
}
calendarUrl
=
{
generateCalendarUrl
}
openCalendarAsWebcal
=
{
openCalendarAsWebcal
}
downloadIcs
=
{
downloadIcs
}
/>
</
div
>
);
}
...
...
schedules_web/src/components/ScheduleRoot.tsx
View file @
c9553734
import
*
as
React
from
'
react
'
;
import
CourseSection
from
'
../util/CourseSection
'
;
import
ScheduleBadge
from
'
./ScheduleBadge
'
;
import
ApiService
from
'
../util/ApiService
'
;
import
{
downloadFile
}
from
'
../util/utilities
'
;
interface
ScheduleRootProps
{
schedule
:
CourseSection
[];
removeCourseSection
:
(
courseSection
:
CourseSection
)
=>
any
;
generateCalendarUrl
:
()
=>
string
;
openCalendarAsWebcal
:
()
=>
void
;
downloadIcs
:
()
=>
Promise
<
void
>
;
}
const
generateSchedule
=
async
(
schedule
:
CourseSection
[])
=>
{
const
crns
=
schedule
.
map
(
section
=>
section
.
crn
);
ApiService
.
subscribeToCalendar
(
crns
);
};
const
ScheduleRoot
=
({
schedule
,
removeCourseSection
}:
ScheduleRootProps
)
=>
(
const
ScheduleRoot
=
({
schedule
,
removeCourseSection
,
generateCalendarUrl
,
openCalendarAsWebcal
,
downloadIcs
,
}:
ScheduleRootProps
)
=>
(
<
div
>
<
ScheduleBadge
schedule
=
{
schedule
}
removeCourseSection
=
{
removeCourseSection
}
generateCalendar
=
{
generateSchedule
}
generateCalendarUrl
=
{
generateCalendarUrl
}
openCalendarAsWebcal
=
{
openCalendarAsWebcal
}
downloadIcs
=
{
downloadIcs
}
/>
{
/* <ScheduleList courses={schedule} selectCourseCallback={removeCourseSection} /> */
}
{
/* <button onClick={generateSchedule}>Generate Schedule</button> */
}
...
...
schedules_web/src/containers/Schedule.tsx
View file @
c9553734
...
...
@@ -2,11 +2,26 @@ import { connect } from 'react-redux';
import
{
removeCourseSection
}
from
'
../actions/schedule/schedule.actions
'
;
import
ScheduleRoot
from
'
../components/ScheduleRoot
'
;
import
{
State
}
from
'
../reducers
'
;
import
CourseSection
from
'
../util/CourseSection
'
;
import
ApiService
from
'
../util/ApiService
'
;
import
{
downloadFile
}
from
'
../util/utilities
'
;
const
mapStateToProps
=
(
state
:
State
)
=>
({
// Takes the current Redux state and returns objects which will be
// passed to the component as Props
const
mapStateToProps
=
(
state
:
State
)
=>
{
const
crns
=
state
.
schedule
?
state
.
schedule
.
map
(
section
=>
section
.
crn
)
:
[];
return
{
schedule
:
state
.
schedule
,
});
generateCalendarUrl
:
()
=>
ApiService
.
generateCalendarUrl
(
crns
),
openCalendarAsWebcal
:
()
=>
ApiService
.
openCalendarAsWebcal
(
crns
),
downloadIcs
:
async
()
=>
{
const
icsText
=
await
ApiService
.
fetchICal
(
crns
);
downloadFile
(
icsText
,
'
GMU Fall 2018.ics
'
);
},
};
};
// Pass mapStateToProps and other values to the component's props
export
default
connect
(
mapStateToProps
,
{
removeCourseSection
}
...
...
schedules_web/src/util/ApiService.ts
View file @
c9553734
...
...
@@ -9,8 +9,12 @@ class ApiService {
searchCourseSections
=
async
(
crn
:
string
):
Promise
<
any
[]
>
=>
fetchJson
(
`
${
this
.
apiRoot
}
/course_sections?crn=
${
crn
}
`
);
subscribeToCalendar
=
(
crns
:
string
[])
=>
generateCalendarUrl
=
(
crns
:
string
[]):
string
=>
`
${
this
.
apiRoot
}
/schedules?crns=
${
crns
.
join
(
'
,
'
)}
`
;
openCalendarAsWebcal
=
(
crns
:
string
[])
=>
{
window
.
open
(
`
${
this
.
webcalUrl
}
/schedules?crns=
${
crns
.
join
(
'
,
'
)}
`
,
'
_self
'
);
};
fetchICal
=
async
(
crns
:
string
[]):
Promise
<
string
>
=>
fetch
(
this
.
generateCalendarUrl
(
crns
)).
then
(
response
=>
response
.
text
());
}
const
fetchJson
=
async
(
url
:
string
):
Promise
<
any
>
=>
fetch
(
url
).
then
(
response
=>
response
.
json
());
...
...
@@ -24,7 +28,7 @@ const postJson = (endpoint: string, data: any): Promise<Response> =>
});
const
local
=
'
localhost:3000/api
'
;
const
remote
=
`
${
window
.
location
.
hostname
}
/api`
const
remote
=
`
${
window
.
location
.
hostname
}
/api`
;
const
apiUrl
=
process
.
env
.
NODE_ENV
===
'
development
'
?
`http://
${
local
}
`
:
`https://
${
remote
}
`
;
const
webcalUrl
=
process
.
env
.
NODE_ENV
===
'
development
'
?
`webcal://
${
local
}
`
:
`webcal://
${
remote
}
`
;
...
...
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