Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
P
pvk-tool
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
13
Issues
13
List
Boards
Labels
Service Desk
Milestones
Merge Requests
2
Merge Requests
2
Operations
Operations
Incidents
Packages & Registries
Packages & Registries
Container Registry
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
amiv
pvk-tool
Commits
1e2deb32
Commit
1e2deb32
authored
Nov 28, 2017
by
Alexander Dietmüller
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Frontend: Talk to backend and display courses in sidebar
parent
a830b71e
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
149 additions
and
17 deletions
+149
-17
Frontend/index.html
Frontend/index.html
+2
-2
Frontend/src/CourseList.js
Frontend/src/CourseList.js
+19
-0
Frontend/src/Layout.js
Frontend/src/Layout.js
+2
-1
Frontend/src/Pvk.js
Frontend/src/Pvk.js
+1
-2
Frontend/src/UserSidebar.js
Frontend/src/UserSidebar.js
+25
-5
Frontend/src/api.js
Frontend/src/api.js
+99
-7
README.md
README.md
+1
-0
No files found.
Frontend/index.html
View file @
1e2deb32
...
...
@@ -6,13 +6,13 @@
main
{
display
:
inline-block
;
vertical-align
:
top
;
width
:
7
0%
;
width
:
6
0%
;
}
aside
{
display
:
inline-block
;
vertical-align
:
top
;
width
:
2
5%
;
width
:
3
5%
;
margin-right
:
5%
;
}
</style>
...
...
Frontend/src/CourseList.js
View file @
1e2deb32
import
PvkList
from
'
./PvkList
'
;
const
m
=
require
(
'
mithril
'
);
const
{
Courses
,
UserCourses
}
=
require
(
'
./api.js
'
);
module
.
exports
=
{
oninit
()
{
Courses
.
load
();
},
view
()
{
<<<<<<<
HEAD
return
m
(
'
div
'
,
[
m
(
PvkList
)]);
=======
// return m('div', 'Hellooo!');
return
m
(
'
ul
'
,
[
Courses
.
list
.
map
(
course
=>
m
(
'
li
'
,
[
m
(
'
p
'
,
`
${
course
.
lecture
.
title
}
,
${
course
.
assistant
}
`
),
m
(
'
button
'
,
{
onclick
()
{
UserCourses
.
select
(
course
);
}
},
'
Add Course
'
,
),
])),
]);
// m('button', { onclick() { Courses.select(); } }, 'Add Course');
>>>>>>>
Frontend
:
Talk
to
backend
and
display
courses
in
sidebar
},
};
Frontend/src/Layout.js
View file @
1e2deb32
...
...
@@ -80,7 +80,8 @@ const LoginPage = {
const
SidebarHeader
=
{
view
()
{
return
[
m
(
'
h1
'
,
'
PVK Tool Demo
'
),
m
(
'
header
'
,
m
(
'
img
'
,
{
src
:
'
/home/alex/contractor/contractor/static/logo.svg
'
})),
// m('h1', 'PVK Tool Demo'),
m
(
'
p
'
,
`Hello,
${
Session
.
user
.
name
}
`
),
m
(
'
button
'
,
{
onclick
:
logout
},
'
Logout
'
),
Session
.
admin
?
[
...
...
Frontend/src/Pvk.js
View file @
1e2deb32
import
m
from
'
mithril
'
;
import
{
apiUrl
}
from
'
./api
'
;
class
Pvk
{
constructor
()
{
...
...
@@ -11,7 +10,7 @@ class Pvk {
// request is needed to force mithrijs to update shared objects
m
.
request
({
method
:
'
GET
'
,
url
:
`
${
apiUrl
}
`
,
//
url: `${apiUrl}`,
}).
then
(()
=>
{
this
.
list
=
[{
lecture
:
{
...
...
Frontend/src/UserSidebar.js
View file @
1e2deb32
// User Sidebar
import
Pvk
from
'
./Pvk
'
;
const
m
=
require
(
'
mithril
'
);
const
{
UserCourses
}
=
require
(
'
./api.js
'
);
function
courseView
(
course
)
{
return
m
(
'
li
'
,
`
${
course
.
lecture
.
title
}
,
${
course
.
assistant
}
`
);
}
function
asList
(
courses
)
{
return
courses
.
map
(
courseView
);
}
module
.
exports
=
{
oninit
()
{
UserCourses
.
load
();
},
view
()
{
return
[
m
(
'
h2
'
,
'
Your Courses
'
),
m
(
'
p
'
,
'
You are not signed up for anything yet.
'
),
m
(
'
p
'
,
`Amnt of Pvks:
${
Pvk
.
list
.
length
}
`
),
m
(
'
h1
'
,
'
Selected Courses
'
),
UserCourses
.
selected
.
length
?
[
asList
(
UserCourses
.
selected
),
m
(
'
button
'
,
{
onclick
()
{
UserCourses
.
reserve
();
}
},
'
reserve
'
),
]
:
m
(
'
p
'
,
'
No courses selected.
'
),
m
(
'
h1
'
,
'
Reserved Courses
'
),
UserCourses
.
reserved
.
length
?
[
asList
(
UserCourses
.
reserved
),
m
(
'
button
'
,
{
onclick
()
{
UserCourses
.
pay
();
}
},
'
Pay
'
),
]
:
m
(
'
p
'
,
'
No courses reserved.
'
),
m
(
'
h1
'
,
'
Accepted Courses
'
),
UserCourses
.
accepted
.
length
?
[
asList
(
UserCourses
.
accepted
),
]
:
m
(
'
p
'
,
'
No courses accepted.
'
),
];
},
};
Frontend/src/api.js
View file @
1e2deb32
...
...
@@ -3,11 +3,15 @@
const
m
=
require
(
'
mithril
'
);
const
ls
=
require
(
'
local-storage
'
);
const
apiUrl
=
'
https://amiv-api.ethz.ch
'
;
const
amivApiUrl
=
'
https://amiv-api.ethz.ch
'
;
const
pvkApiUrl
=
`//
${
window
.
location
.
hostname
}
/api`
;
const
adminGroupName
=
'
PVK Admins
'
;
const
storedSession
=
ls
(
'
session
'
);
// Session with AMIVAPI
const
Session
=
{
// Quick check if session exists
active
()
{
return
this
.
data
.
token
;
},
...
...
@@ -43,7 +47,7 @@ const Session = {
// Login and request user data along with the session
return
m
.
request
({
method
:
'
POST
'
,
url
:
`
${
apiUrl
}
/sessions?embedded={"user": 1}`
,
url
:
`
${
a
mivA
piUrl
}
/sessions?embedded={"user": 1}`
,
data
:
{
username
,
password
},
}).
then
((
data
)
=>
{
// Session data
...
...
@@ -71,7 +75,7 @@ const Session = {
if
(
this
.
data
.
token
)
{
return
m
.
request
({
method
:
'
DELETE
'
,
url
:
`
${
apiUrl
}
/sessions/
${
this
.
data
.
_id
}
`
,
url
:
`
${
a
mivA
piUrl
}
/sessions/
${
this
.
data
.
_id
}
`
,
headers
:
{
Authorization
:
`Token
${
this
.
data
.
token
}
`
,
'
If-Match
'
:
this
.
data
.
_etag
,
...
...
@@ -83,7 +87,7 @@ const Session = {
// Token already no valid anymore, clear session
this
.
clear
();
}
else
{
throw
err
;
throw
err
.
_error
;
}
});
}
...
...
@@ -99,7 +103,7 @@ const Session = {
});
m
.
request
({
method
:
'
GET
'
,
url
:
`
${
apiUrl
}
/groups?
${
query
}
`
,
url
:
`
${
a
mivA
piUrl
}
/groups?
${
query
}
`
,
headers
:
{
Authorization
:
`Token
${
token
}
`
},
}).
then
((
data
)
=>
{
if
(
data
.
_meta
.
total
!==
0
)
{
...
...
@@ -112,7 +116,7 @@ const Session = {
});
return
m
.
request
({
method
:
'
GET
'
,
url
:
`
${
apiUrl
}
/groupmemberships?
${
query
}
`
,
url
:
`
${
a
mivA
piUrl
}
/groupmemberships?
${
query
}
`
,
headers
:
{
Authorization
:
`Token
${
token
}
`
},
});
}
...
...
@@ -132,7 +136,95 @@ const Session = {
},
};
// Request to the PVK backend
function
request
({
resource
,
method
=
'
GET
'
,
id
=
''
,
data
=
{},
query
=
{},
})
{
// Parse query such that the backend understands it
const
parsedQuery
=
{};
Object
.
keys
(
query
).
forEach
((
key
)
=>
{
parsedQuery
[
key
]
=
JSON
.
stringify
(
query
[
key
]);
});
const
queryString
=
m
.
buildQueryString
(
parsedQuery
);
// Send the request
return
m
.
request
({
method
,
data
,
url
:
`
${
pvkApiUrl
}
/
${
resource
}
/
${
id
}
?
${
queryString
}
`
,
headers
:
{
Authorization
:
`Token
${
Session
.
data
.
token
}
`
},
}).
catch
((
err
)
=>
{
// If the error is 401, the token is invalid -> auto log out
if
(
err
.
_error
.
code
===
401
)
{
Session
.
clear
();
}
// Actual error information is in the '_error' field, pass this on
throw
err
.
_error
;
});
}
// Generic PVK resource
class
Resource
{
constructor
(
name
,
query
=
{})
{
this
.
name
=
name
;
this
.
list
=
[];
this
.
query
=
query
;
}
load
()
{
return
request
({
resource
:
this
.
name
,
query
:
this
.
query
}).
then
((
data
)
=>
{
// Fill own list
this
.
list
=
data
.
_items
;
// Pass on data
return
data
;
});
}
}
const
UserCourses
=
{
resources
:
{
selections
:
new
Resource
(
'
selections
'
,
{
where
:
{
nethz
:
Session
.
user
.
nethz
}
},
),
signups
:
new
Resource
(
'
signups
'
,
{
where
:
{
nethz
:
Session
.
user
.
nethz
}
},
),
},
load
()
{
this
.
resources
.
selections
.
load
().
then
(()
=>
{
// We are only interested in one the first (and single) element
this
.
resources
.
selections
.
list
=
this
.
resources
.
selections
.
list
[
0
]
||
[];
});
this
.
resources
.
signups
.
load
();
},
get
selected
()
{
return
this
.
resources
.
selections
.
list
;
},
get
reserved
()
{
return
this
.
resources
.
signups
.
list
.
filter
(({
status
})
=>
status
===
'
reserved
'
);
},
get
accepted
()
{
return
this
.
resources
.
signups
.
list
.
filter
(({
status
})
=>
status
===
'
accepted
'
);
},
// TODO(Alex)
select
()
{},
reserve
()
{},
pay
()
{},
};
const
Courses
=
new
Resource
(
'
courses
'
,
{
embedded
:
{
lecture
:
1
}
});
module
.
exports
=
{
Session
,
apiUrl
,
request
,
UserCourses
,
Courses
,
};
README.md
View file @
1e2deb32
...
...
@@ -41,6 +41,7 @@ frontend development. Here's how:
-e
MONGO_HOST
=
"mongodb"
\
pvk
```
The
`--link`
and
`-e`
make sure the backend can access the db container.
And now the backend is available at port 80, ready to use!
...
...
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