Merge remote-tracking branch 'origin/master' into feat/exercises
This commit is contained in:
commit
8725f935d0
@ -1,7 +1,7 @@
|
|||||||
SummerTerm year@Integer: Sommersemester #{tshow year}
|
SummerTerm year@Integer: Sommersemester #{tshow year}
|
||||||
WinterTerm year@Integer: Wintersemester #{tshow year}/#{tshow $ succ year}
|
WinterTerm year@Integer: Wintersemester #{tshow year}/#{tshow $ succ year}
|
||||||
PSLimitNonPositive: “pagesize” muss größer als null sein
|
PSLimitNonPositive: “pagesize” muss größer als null sein
|
||||||
Page n@Int64 num@Int64: Seite #{tshow n} von #{tshow num}
|
Page n@Int64: #{tshow n}
|
||||||
TermEdited tid@TermIdentifier: Semester #{termToText tid} erfolgreich editiert.
|
TermEdited tid@TermIdentifier: Semester #{termToText tid} erfolgreich editiert.
|
||||||
TermNewTitle: Semester editiere/anlegen.
|
TermNewTitle: Semester editiere/anlegen.
|
||||||
InvalidInput: Eingaben bitte korrigieren.
|
InvalidInput: Eingaben bitte korrigieren.
|
||||||
|
|||||||
@ -96,9 +96,14 @@ data MenuItem = MenuItem
|
|||||||
{ menuItemLabel :: Text
|
{ menuItemLabel :: Text
|
||||||
, menuItemIcon :: Maybe Text
|
, menuItemIcon :: Maybe Text
|
||||||
, menuItemRoute :: Route UniWorX
|
, menuItemRoute :: Route UniWorX
|
||||||
, menuItemAccessCallback :: Handler Bool
|
, menuItemAccessCallback' :: Handler Bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
menuItemAccessCallback :: MenuItem -> Handler Bool
|
||||||
|
menuItemAccessCallback MenuItem{..} = (&&) <$> ((==) Authorized <$> authCheck) <*> menuItemAccessCallback'
|
||||||
|
where
|
||||||
|
authCheck = handleAny (\_ -> return . Unauthorized $ error "authCheck caught exception") $ isAuthorized menuItemRoute False
|
||||||
|
|
||||||
data MenuTypes -- Semantische Rolle:
|
data MenuTypes -- Semantische Rolle:
|
||||||
= NavbarAside { menuItem :: MenuItem } -- TODO
|
= NavbarAside { menuItem :: MenuItem } -- TODO
|
||||||
| NavbarExtra { menuItem :: MenuItem } -- TODO
|
| NavbarExtra { menuItem :: MenuItem } -- TODO
|
||||||
@ -357,49 +362,49 @@ defaultLinks = -- Define the menu items of the header.
|
|||||||
{ menuItemLabel = "Home"
|
{ menuItemLabel = "Home"
|
||||||
, menuItemIcon = Just "home"
|
, menuItemIcon = Just "home"
|
||||||
, menuItemRoute = HomeR
|
, menuItemRoute = HomeR
|
||||||
, menuItemAccessCallback = return True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
, NavbarRight $ MenuItem
|
, NavbarRight $ MenuItem
|
||||||
{ menuItemLabel = "Profile"
|
{ menuItemLabel = "Profile"
|
||||||
, menuItemIcon = Just "profile"
|
, menuItemIcon = Just "profile"
|
||||||
, menuItemRoute = ProfileR
|
, menuItemRoute = ProfileR
|
||||||
, menuItemAccessCallback = isJust <$> maybeAuthPair
|
, menuItemAccessCallback' = isJust <$> maybeAuthPair
|
||||||
}
|
}
|
||||||
, NavbarSecondary $ MenuItem
|
, NavbarSecondary $ MenuItem
|
||||||
{ menuItemLabel = "Login"
|
{ menuItemLabel = "Login"
|
||||||
, menuItemIcon = Just "login"
|
, menuItemIcon = Just "login"
|
||||||
, menuItemRoute = AuthR LoginR
|
, menuItemRoute = AuthR LoginR
|
||||||
, menuItemAccessCallback = isNothing <$> maybeAuthPair
|
, menuItemAccessCallback' = isNothing <$> maybeAuthPair
|
||||||
}
|
}
|
||||||
, NavbarSecondary $ MenuItem
|
, NavbarSecondary $ MenuItem
|
||||||
{ menuItemLabel = "Logout"
|
{ menuItemLabel = "Logout"
|
||||||
, menuItemIcon = Just "logout"
|
, menuItemIcon = Just "logout"
|
||||||
, menuItemRoute = AuthR LogoutR
|
, menuItemRoute = AuthR LogoutR
|
||||||
, menuItemAccessCallback = isJust <$> maybeAuthPair
|
, menuItemAccessCallback' = isJust <$> maybeAuthPair
|
||||||
}
|
}
|
||||||
, NavbarAside $ MenuItem
|
, NavbarAside $ MenuItem
|
||||||
{ menuItemLabel = "Aktuelle Veranstaltungen"
|
{ menuItemLabel = "Aktuelle Veranstaltungen"
|
||||||
, menuItemIcon = Just "book"
|
, menuItemIcon = Just "book"
|
||||||
, menuItemRoute = CourseListR -- should be CourseListActiveR or similar in the future
|
, menuItemRoute = CourseListR -- should be CourseListActiveR or similar in the future
|
||||||
, menuItemAccessCallback = return True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
, NavbarAside $ MenuItem
|
, NavbarAside $ MenuItem
|
||||||
{ menuItemLabel = "Alte Veranstaltungen"
|
{ menuItemLabel = "Alte Veranstaltungen"
|
||||||
, menuItemIcon = Just "book"
|
, menuItemIcon = Just "book"
|
||||||
, menuItemRoute = CourseListR -- should be CourseListInactiveR or similar in the future
|
, menuItemRoute = CourseListR -- should be CourseListInactiveR or similar in the future
|
||||||
, menuItemAccessCallback = return True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
, NavbarAside $ MenuItem
|
, NavbarAside $ MenuItem
|
||||||
{ menuItemLabel = "Veranstaltungen"
|
{ menuItemLabel = "Veranstaltungen"
|
||||||
, menuItemIcon = Just "book"
|
, menuItemIcon = Just "book"
|
||||||
, menuItemRoute = CourseListR
|
, menuItemRoute = CourseListR
|
||||||
, menuItemAccessCallback = return True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
, NavbarAside $ MenuItem
|
, NavbarAside $ MenuItem
|
||||||
{ menuItemLabel = "Benutzer"
|
{ menuItemLabel = "Benutzer"
|
||||||
, menuItemIcon = Just "user"
|
, menuItemIcon = Just "user"
|
||||||
, menuItemRoute = UsersR
|
, menuItemRoute = UsersR
|
||||||
, menuItemAccessCallback = return True -- Creates a LOOP: (Authorized ==) <$> isAuthorized UsersR False
|
, menuItemAccessCallback' = return True -- Creates a LOOP: (Authorized ==) <$> isAuthorized UsersR False
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@ -68,7 +68,7 @@ getCourseListTermR tidini = do
|
|||||||
{ menuItemLabel = "Neuer Kurs"
|
{ menuItemLabel = "Neuer Kurs"
|
||||||
, menuItemIcon = Just "book"
|
, menuItemIcon = Just "book"
|
||||||
, menuItemRoute = CourseNewR
|
, menuItemRoute = CourseNewR
|
||||||
, menuItemAccessCallback = (== Authorized) <$> isAuthorized CourseNewR False
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
let coursesTable = encodeWidgetTable tableSortable colonnadeTerms courses
|
let coursesTable = encodeWidgetTable tableSortable colonnadeTerms courses
|
||||||
@ -97,7 +97,7 @@ getCourseShowR tid csh = do
|
|||||||
{ menuItemLabel = "Übungsblätter"
|
{ menuItemLabel = "Übungsblätter"
|
||||||
, menuItemIcon = Nothing
|
, menuItemIcon = Nothing
|
||||||
, menuItemRoute = CSheetR tid csh SheetListR
|
, menuItemRoute = CSheetR tid csh SheetListR
|
||||||
, menuItemAccessCallback = (== Authorized) <$> isAuthorized (CSheetR tid csh SheetListR) False
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
defaultLinkLayout pageActions $ do
|
defaultLinkLayout pageActions $ do
|
||||||
|
|||||||
@ -168,7 +168,7 @@ getSheetList courseEnt = do
|
|||||||
{ menuItemLabel = "Neues Übungsblatt"
|
{ menuItemLabel = "Neues Übungsblatt"
|
||||||
, menuItemIcon = Nothing
|
, menuItemIcon = Nothing
|
||||||
, menuItemRoute = CSheetR tid csh SheetNewR
|
, menuItemRoute = CSheetR tid csh SheetNewR
|
||||||
, menuItemAccessCallback = (== Authorized) <$> isAuthorized CourseNewR False
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
defaultLinkLayout pageActions $ do
|
defaultLinkLayout pageActions $ do
|
||||||
|
|||||||
@ -94,7 +94,7 @@ getTermShowR = do
|
|||||||
{ menuItemLabel = "Neues Semester"
|
{ menuItemLabel = "Neues Semester"
|
||||||
, menuItemIcon = Nothing
|
, menuItemIcon = Nothing
|
||||||
, menuItemRoute = TermEditR
|
, menuItemRoute = TermEditR
|
||||||
, menuItemAccessCallback = (== Authorized) <$> isAuthorized TermEditR True
|
, menuItemAccessCallback' = return True
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
defaultLinkLayout pageActions $ do
|
defaultLinkLayout pageActions $ do
|
||||||
|
|||||||
@ -152,11 +152,18 @@ dbTable PSValidator{..} DBTable{ dbtIdent = (toPathPiece -> dbtIdent), .. } = do
|
|||||||
getParams <- handlerToWidget $ queryToQueryText . Wai.queryString . reqWaiRequest <$> getRequest
|
getParams <- handlerToWidget $ queryToQueryText . Wai.queryString . reqWaiRequest <$> getRequest
|
||||||
let table = $(widgetFile "table/colonnade")
|
let table = $(widgetFile "table/colonnade")
|
||||||
pageCount = max 1 . ceiling $ rowCount % psLimit
|
pageCount = max 1 . ceiling $ rowCount % psLimit
|
||||||
|
pageNumbers = [0..pred pageCount]
|
||||||
tblLink f = decodeUtf8 . Builder.toLazyByteString . renderQueryText True $ f getParams
|
tblLink f = decodeUtf8 . Builder.toLazyByteString . renderQueryText True $ f getParams
|
||||||
|
|
||||||
withSortLinks Sortable{ sortableContent = Cell{..}, .. } = Cell
|
withSortLinks Sortable{ sortableContent = Cell{..}, .. } = Cell
|
||||||
{ cellContents = $(widgetFile "table/sortable-header")
|
{ cellContents = $(widgetFile "table/sortable-header")
|
||||||
, ..
|
, cellAttrs = maybe mempty (const sortableAttr) sortableKey <> cellAttrs
|
||||||
}
|
}
|
||||||
|
where
|
||||||
|
directions = [dir | (k, dir) <- psSorting, Just k == sortableKey ]
|
||||||
|
sortableAttr = Html5.class_ . fromString . unwords $ "sortable" : foldMap toAttr directions
|
||||||
|
toAttr SortAsc = ["sorted-asc"]
|
||||||
|
toAttr SortDesc = ["sorted-desc"]
|
||||||
$(widgetFile "table/layout")
|
$(widgetFile "table/layout")
|
||||||
where
|
where
|
||||||
tblLayout :: Widget -> Handler Html
|
tblLayout :: Widget -> Handler Html
|
||||||
|
|||||||
@ -20,7 +20,8 @@
|
|||||||
--fontbase: #34303a;
|
--fontbase: #34303a;
|
||||||
--fontsec: #5b5861;
|
--fontsec: #5b5861;
|
||||||
/* THEME 4 */
|
/* THEME 4 */
|
||||||
--darkbase: #263C4C;
|
--darkerbase: #274a65;
|
||||||
|
--darkbase: #425d79;
|
||||||
--lightbase: #598EB5;
|
--lightbase: #598EB5;
|
||||||
--lighterbase: #5F98C2;
|
--lighterbase: #5F98C2;
|
||||||
--whitebase: #FCFFFA;
|
--whitebase: #FCFFFA;
|
||||||
|
|||||||
@ -70,7 +70,7 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
width: 30px;
|
width: 30px;
|
||||||
height: 30px;
|
height: 30px;
|
||||||
background-color: var(--darkbase);
|
background-color: var(--darkerbase);
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
z-index: 20;
|
z-index: 20;
|
||||||
|
|||||||
@ -1,61 +0,0 @@
|
|||||||
(function collonadeClosure() {
|
|
||||||
'use strict';
|
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', function DOMContentLoaded() {
|
|
||||||
|
|
||||||
var ASC = 'asc';
|
|
||||||
var DESC = 'desc';
|
|
||||||
|
|
||||||
// TODO: Make use of interpolated dbtIdent
|
|
||||||
var table = document.querySelector('table');
|
|
||||||
var ths = Array.from(table.querySelectorAll('th'));
|
|
||||||
|
|
||||||
// attach click handler to each table-header
|
|
||||||
ths.map(function(th) {
|
|
||||||
var link = th.querySelector('a');
|
|
||||||
if (link) {
|
|
||||||
link.addEventListener('click', clickHandler);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// handles click on table header
|
|
||||||
function clickHandler(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
var url = new URL(window.location.origin + window.location.pathname + this.getAttribute('href'));
|
|
||||||
var order = this.parentNode.dataset.order || ASC;
|
|
||||||
// TODO: not working here... getting whole page as response...
|
|
||||||
url.searchParams.set('table-only', 'true');
|
|
||||||
updateTableFrom(url);
|
|
||||||
markSorted(this.parentNode, order);
|
|
||||||
}
|
|
||||||
|
|
||||||
function markSorted(th, order) {
|
|
||||||
ths.forEach(function(th) {
|
|
||||||
th.classList.remove('sorted-asc', 'sorted-desc');
|
|
||||||
});
|
|
||||||
th.classList.add('sorted-' + order);
|
|
||||||
th.dataset.order = order;
|
|
||||||
}
|
|
||||||
|
|
||||||
// fetches new sorted table from url with params and replaces contents of current table
|
|
||||||
function updateTableFrom(url) {
|
|
||||||
fetch(url, {
|
|
||||||
headers: {
|
|
||||||
'Accept': 'text/html'
|
|
||||||
}
|
|
||||||
}).then(function(response) {
|
|
||||||
var contentType = response.headers.get("content-type");
|
|
||||||
if (!response.ok) {
|
|
||||||
throw ('Looks like there was a problem fetching ' + url.toString() + '. Status Code: ' + response.status);
|
|
||||||
}
|
|
||||||
return response.text();
|
|
||||||
}).then(function(data) {
|
|
||||||
// replace contents of table body
|
|
||||||
table.querySelector('tbody').innerHTML = data;
|
|
||||||
}).catch(function(err) {
|
|
||||||
console.error(err);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
})();
|
|
||||||
@ -1,7 +1,14 @@
|
|||||||
table th {
|
table th {
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-right: 20px;
|
padding-right: 20px;
|
||||||
|
|
||||||
|
&.sortable {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
font-weight: 800;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
table th.sorted-asc,
|
table th.sorted-asc,
|
||||||
@ -9,12 +16,11 @@ table th.sorted-desc {
|
|||||||
color: var(--lightbase);
|
color: var(--lightbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
table th.sorted-asc::after,
|
table th.sortable::after,
|
||||||
table th.sorted-desc::after {
|
table th.sortable::before {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 0;
|
right: 0;
|
||||||
top: 15px;
|
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
height: 0;
|
||||||
transform: translateY(-100%);
|
transform: translateY(-100%);
|
||||||
@ -22,7 +28,15 @@ table th.sorted-desc::after {
|
|||||||
border-right: 8px solid transparent;
|
border-right: 8px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
table th.sorted-asc::after {
|
table th.sortable::before {
|
||||||
|
top: 21px;
|
||||||
|
border-top: 8px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
table th.sortable::after {
|
||||||
|
top: 9px;
|
||||||
|
border-bottom: 8px solid rgba(0, 0, 0, 0.1);
|
||||||
|
}
|
||||||
|
table th.sorted-asc::before {
|
||||||
border-top: 8px solid var(--lightbase);
|
border-top: 8px solid var(--lightbase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,6 +1,10 @@
|
|||||||
<div .table>
|
$newline never
|
||||||
^{table}
|
<div ##{dbtIdent}-table-wrapper>
|
||||||
|
<div .scrolltable>
|
||||||
|
^{table}
|
||||||
$if pageCount > 1
|
$if pageCount > 1
|
||||||
<p style="text-align:center">
|
<ul ##{dbtIdent}-pagination .pagination>
|
||||||
$# TODO: foreach (reachable pages) print link to that page
|
$forall p <- pageNumbers
|
||||||
_{MsgPage (succ psPage) pageCount}
|
<li .pagination-link :p == psPage:.current>
|
||||||
|
<a href=#{tblLink $ setParam (wIdent "page") (Just $ tshow p)}>
|
||||||
|
_{MsgPage (succ p)}
|
||||||
|
|||||||
70
templates/table/layout.julius
Normal file
70
templates/table/layout.julius
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
(function collonadeClosure() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', function DOMContentLoaded() {
|
||||||
|
|
||||||
|
var ASC = 'asc';
|
||||||
|
var DESC = 'desc';
|
||||||
|
|
||||||
|
function setupAsync(wrapper) {
|
||||||
|
|
||||||
|
var table = wrapper.querySelector('#' + #{String $ dbtIdent});
|
||||||
|
var ths = Array.from(table.querySelectorAll('th.sortable'));
|
||||||
|
if (ths) {
|
||||||
|
// attach click handler to each sortable column if any
|
||||||
|
ths.forEach(function(th) {
|
||||||
|
th.addEventListener('click', clickHandler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagination = wrapper.querySelector('#' + #{String $ dbtIdent} + '-pagination');
|
||||||
|
if (pagination) {
|
||||||
|
var paginationLinks = Array.from(pagination.querySelectorAll('.pagination-link'));
|
||||||
|
// attach click handler to pagination links if any
|
||||||
|
paginationLinks.forEach(function(p) {
|
||||||
|
p.addEventListener('click', clickHandler);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function clickHandler(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
var url = new URL(window.location.origin + window.location.pathname + getClickDestination(this));
|
||||||
|
url.searchParams.set(#{String $ wIdent "table-only"}, 'yes');
|
||||||
|
updateTableFrom(url);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getClickDestination(el) {
|
||||||
|
var link = el.querySelector('a');
|
||||||
|
if (!link) { return false; }
|
||||||
|
return link.getAttribute('href');
|
||||||
|
}
|
||||||
|
|
||||||
|
// fetches new sorted table from url with params and replaces contents of current table
|
||||||
|
function updateTableFrom(url) {
|
||||||
|
fetch(url, {
|
||||||
|
credentials: 'same-origin',
|
||||||
|
headers: {
|
||||||
|
'Accept': 'text/html'
|
||||||
|
}
|
||||||
|
}).then(function(response) {
|
||||||
|
var contentType = response.headers.get("content-type");
|
||||||
|
if (!response.ok) {
|
||||||
|
throw ('Looks like there was a problem fetching ' + url.toString() + '. Status Code: ' + response.status);
|
||||||
|
}
|
||||||
|
return response.text();
|
||||||
|
}).then(function(data) {
|
||||||
|
// replace contents of table body
|
||||||
|
wrapper.innerHTML = data;
|
||||||
|
// set up async functionality again
|
||||||
|
setupAsync(wrapper);
|
||||||
|
table.querySelector('tbody').innerHTML = data;
|
||||||
|
}).catch(function(err) {
|
||||||
|
console.error(err);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var selector = '#' + #{String $ dbtIdent} + '-table-wrapper';
|
||||||
|
setupAsync(document.querySelector(selector));
|
||||||
|
});
|
||||||
|
})();
|
||||||
38
templates/table/layout.lucius
Normal file
38
templates/table/layout.lucius
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
.pagination {
|
||||||
|
margin-top: 20px;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
.pagination-link {
|
||||||
|
margin: 0 7px;
|
||||||
|
display: inline-block;
|
||||||
|
background-color: var(--greybase);
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--whitebase);
|
||||||
|
padding: 7px 13px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(.current):hover {
|
||||||
|
background-color: var(--lighterbase);
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: var(--whitebase);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.current {
|
||||||
|
pointer-events: none;
|
||||||
|
background-color: var(--lightbase);
|
||||||
|
|
||||||
|
a {
|
||||||
|
text-decoration: underline;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:last-child {
|
||||||
|
margin-right: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,7 +1,10 @@
|
|||||||
^{cellContents}
|
|
||||||
$maybe flag <- sortableKey
|
$maybe flag <- sortableKey
|
||||||
<br>
|
$case directions
|
||||||
<a href=#{tblLink $ setParam (wIdent "sorting") (Just $ flag <> "-asc")}>asc
|
$of [SortAsc]
|
||||||
/
|
<a href=#{tblLink $ setParam (wIdent "sorting") (Just $ flag <> "-desc")}>
|
||||||
<a href=#{tblLink $ setParam (wIdent "sorting") (Just $ flag <> "-desc")}>desc
|
^{cellContents}
|
||||||
|
$of _
|
||||||
|
<a href=#{tblLink $ setParam (wIdent "sorting") (Just $ flag <> "-asc")}>
|
||||||
|
^{cellContents}
|
||||||
$nothing
|
$nothing
|
||||||
|
^{cellContents}
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
<div .container>
|
<div .container>
|
||||||
<h1>Semesterübersicht
|
<h1>Semesterübersicht
|
||||||
|
|
||||||
<div .scrolltable>
|
^{table}
|
||||||
^{table}
|
|
||||||
|
|||||||
@ -18,10 +18,11 @@ $newline never
|
|||||||
WiSe 17/18
|
WiSe 17/18
|
||||||
<ul .asidenav__list>
|
<ul .asidenav__list>
|
||||||
$forall (Entity _ Course{..}) <- favourites
|
$forall (Entity _ Course{..}) <- favourites
|
||||||
<li .asidenav__list-item>
|
$with route <- CourseR courseTermId courseShorthand CourseShowR
|
||||||
<a .asidenav__link-wrapper href=@{CourseR courseTermId courseShorthand CourseShowR}>
|
<li .asidenav__list-item :Just route == mcurrentRoute:.asidenav__list-item--active>
|
||||||
<div .asidenav__link-shorthand>#{courseShorthand}
|
<a .asidenav__link-wrapper href=@{route}>
|
||||||
<div .asidenav__link-label>#{courseName}
|
<div .asidenav__link-shorthand>#{courseShorthand}
|
||||||
|
<div .asidenav__link-label>#{courseName}
|
||||||
|
|
||||||
<li .asidenav__list-item>
|
<li .asidenav__list-item>
|
||||||
<a .asidenav__link-wrapper href="/course/S2018/ixd/show">
|
<a .asidenav__link-wrapper href="/course/S2018/ixd/show">
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
.main__aside {
|
.main__aside {
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: var(--darkbase);
|
background-color: #425d79;
|
||||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
flex: 0 0 300px;
|
flex: 0 0 300px;
|
||||||
@ -22,12 +22,33 @@
|
|||||||
|
|
||||||
.asidenav__box-title {
|
.asidenav__box-title {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
padding: 0;
|
padding: 1px;
|
||||||
|
font-size: 18px;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 0;
|
||||||
|
background-color: var(--fontsec);
|
||||||
}
|
}
|
||||||
|
|
||||||
.asidenav__link-wrapper {
|
.asidenav__link-wrapper {
|
||||||
.asidenav__link-shorthand {
|
.asidenav__link-shorthand {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
position: static;
|
||||||
|
background-color: var(--darkbase);
|
||||||
|
color: var(--whitebase);
|
||||||
|
height: 50px;
|
||||||
|
width: 50px;
|
||||||
|
text-align: center;
|
||||||
|
opacity: 1;
|
||||||
|
font-size: 15px;
|
||||||
|
line-height: 1em;
|
||||||
|
margin-right: 13px;
|
||||||
|
flex-shrink: 0;
|
||||||
|
padding: 1px;
|
||||||
|
outline: 1px solid white;
|
||||||
|
text-transform: uppercase;
|
||||||
|
word-break: break-all;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
}
|
}
|
||||||
.asidenav__link-label {
|
.asidenav__link-label {
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
@ -62,6 +83,9 @@
|
|||||||
|
|
||||||
.asidenav__box-title {
|
.asidenav__box-title {
|
||||||
padding: 7px 13px;
|
padding: 7px 13px;
|
||||||
|
margin-top: 13px;
|
||||||
|
background-color: transparent;
|
||||||
|
transition: all .2s ease;
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: white;
|
color: white;
|
||||||
@ -76,7 +100,9 @@
|
|||||||
color: var(--fontbase);
|
color: var(--fontbase);
|
||||||
transform: translateX(0);
|
transform: translateX(0);
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
transition: all .2s ease;
|
transition: all .2s ease-out;
|
||||||
|
width: 0;
|
||||||
|
overflow: hidden;
|
||||||
z-index: -1;
|
z-index: -1;
|
||||||
|
|
||||||
.asidenav__list-item {
|
.asidenav__list-item {
|
||||||
@ -115,6 +141,7 @@
|
|||||||
.asidenav__nested-list {
|
.asidenav__nested-list {
|
||||||
transform: translateX(100%);
|
transform: translateX(100%);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
|
width: 200px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.asidenav__link-wrapper,
|
.asidenav__link-wrapper,
|
||||||
@ -123,8 +150,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.asidenav__link-shorthand {
|
.asidenav__link-shorthand {
|
||||||
background-color: var(--whitebase);
|
transform: scale(1.05, 1.0);
|
||||||
color: var(--darkbase);
|
transform-origin: right;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -136,6 +163,11 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.asidenav__link-shorthand {
|
||||||
|
transform: scale(1.05, 1.0);
|
||||||
|
transform-origin: right;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.asidenav__link-wrapper {
|
.asidenav__link-wrapper {
|
||||||
@ -152,19 +184,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.asidenav__link-shorthand {
|
.asidenav__link-shorthand {
|
||||||
background-color: var(--darkbase);
|
display: block;
|
||||||
color: var(--whitebase);
|
position: absolute;
|
||||||
height: 50px;
|
color: var(--greybase);
|
||||||
width: 50px;
|
line-height: 50px;
|
||||||
display: none;
|
opacity: 0.3;
|
||||||
text-align: center;
|
right: 10px;
|
||||||
margin-right: 13px;
|
top: 0;
|
||||||
flex-shrink: 0;
|
font-size: 40px;
|
||||||
outline: 1px solid white;
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
word-break: break-all;
|
transition: transform .2s ease;
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.asidenav__link-label {
|
.asidenav__link-label {
|
||||||
|
|||||||
@ -7,11 +7,11 @@
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
height: var(--header-height);
|
height: var(--header-height);
|
||||||
padding-right: 5vw;
|
padding-right: 5vw;
|
||||||
padding-left: 340px;
|
padding-left: 90px;
|
||||||
background: var(--darkbase); /* Old browsers */
|
background: var(--darkerbase); /* Old browsers */
|
||||||
background: -moz-linear-gradient(bottom, var(--darkbase) 0%, #425d79 100%); /* FF3.6-15 */
|
background: -moz-linear-gradient(bottom, var(--darkerbase) 0%, #425d79 100%); /* FF3.6-15 */
|
||||||
background: -webkit-linear-gradient(bottom, var(--darkbase) 0%,#425d79 100%); /* Chrome10-25,Safari5.1-6 */
|
background: -webkit-linear-gradient(bottom, var(--darkerbase) 0%,#425d79 100%); /* Chrome10-25,Safari5.1-6 */
|
||||||
background: linear-gradient(to top, var(--darkbase) 0%,#425d79 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
background: linear-gradient(to top, var(--darkerbase) 0%,#425d79 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */
|
||||||
color: white;
|
color: white;
|
||||||
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
|
box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
@ -86,8 +86,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.navbar .navbar__list-item:not(.navbar__list-item--active):hover {
|
.navbar .navbar__list-item:not(.navbar__list-item--active):hover {
|
||||||
background-color: var(--darkbase);
|
background-color: var(--darkerbase);
|
||||||
color: var(--whitebase);
|
|
||||||
}
|
}
|
||||||
.navbar .navbar__list-item:not(.navbar__list-item--active):hover .navbar__link-wrapper {
|
.navbar .navbar__list-item:not(.navbar__list-item--active):hover .navbar__link-wrapper {
|
||||||
color: var(--whitebase);
|
color: var(--whitebase);
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
$newline never
|
$newline never
|
||||||
$if hasPageActions
|
$if hasPageActions
|
||||||
<div .page-nav-prime>
|
<div .page-nav-prime>
|
||||||
<h3>Aktionen:
|
|
||||||
<ul .pagenav__list>
|
<ul .pagenav__list>
|
||||||
$forall menuType <- menuTypes
|
$forall menuType <- menuTypes
|
||||||
$case menuType
|
$case menuType
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
.page-nav-prime {
|
.page-nav-prime {
|
||||||
background-color: var(--lightgreybase);
|
background-color: var(--lightgreybase);
|
||||||
box-shadow: -20px -20px 0 20px var(--lightgreybase),
|
padding: 13px;
|
||||||
20px -20px 0 20px var(--lightgreybase);
|
|
||||||
padding: 13px 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.page-nav-prime .pagenav__list {
|
.page-nav-prime .pagenav__list {
|
||||||
@ -11,11 +9,5 @@
|
|||||||
}
|
}
|
||||||
.page-nav-prime .pagenav__list-item {
|
.page-nav-prime .pagenav__list-item {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
border-bottom: 2px solid var(--lightbase);
|
|
||||||
margin-right: 7px;
|
margin-right: 7px;
|
||||||
transition: border-bottom-color .2s ease;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
border-bottom-color: var(--lighterbase);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user