Merge branch 'master' into staging

This commit is contained in:
Felix Hamann 2018-07-08 23:54:34 +02:00
commit 69c2e95d83
11 changed files with 94 additions and 44 deletions

1
models
View File

@ -12,6 +12,7 @@ User json
UserAdmin
user UserId
school SchoolId
UniqueUserAdmin user school
UserLecturer
user UserId
school SchoolId

View File

@ -459,7 +459,6 @@ instance Yesod UniWorX where
defaultLayout widget = do
master <- getYesod
mmsgs <- getMessages
messageRender <- getMessageRender -- needed, since there is no i18n interpolation in Julius
mcurrentRoute <- getCurrentRoute
@ -493,10 +492,10 @@ instance Yesod UniWorX where
in (c, courseRoute, ) <$> filterM (menuItemAccessCallback . menuItem) (pageActions courseRoute)
let highlight :: Route UniWorX -> Bool -- highlight last route in breadcrumbs, favorites taking priority
highlight = let crumbs = mcons mcurrentRoute $ fst <$> parents
actFav = List.intersect (snd3 <$> favourites) crumbs
highRs = if null actFav then crumbs else actFav
in \r -> r `elem` highRs
highlight = let crumbs = mcons mcurrentRoute $ fst <$> reverse parents
navItems = map snd3 favourites ++ map (menuItemRoute . menuItem) menuTypes
highR = find (`elem` navItems) . uncurry (++) $ partition (`elem` map snd3 favourites) crumbs
in \r -> Just r == highR
favouriteTerms :: [TermIdentifier]
favouriteTerms = Set.toDescList $ foldMap (\(Course{..}, _, _) -> Set.singleton $ unTermKey courseTerm) favourites
favouriteTerm :: TermIdentifier -> [(Course, Route UniWorX, [MenuTypes])]
@ -655,7 +654,7 @@ submissionList tid csh shn uid = E.select . E.from $ \(course `E.InnerJoin` shee
defaultLinks :: [MenuTypes]
defaultLinks = -- Define the menu items of the header.
[ NavbarRight $ MenuItem
[ NavbarAside $ MenuItem
{ menuItemLabel = "Home"
, menuItemIcon = Just "home"
, menuItemRoute = HomeR

View File

@ -13,6 +13,7 @@ import Import
import Handler.Utils
import qualified Data.Map as Map
import qualified Data.Set as Set
import qualified Database.Esqueleto as E
@ -41,7 +42,7 @@ getUsersR = do
E.orderBy [E.asc $ school E.^. SchoolShorthand]
return $ school E.^. SchoolShorthand
return [whamlet|
<ul>
<ul .list--inline .list--comma-separated>
$forall (E.Value sh) <- schools
<li>#{sh}
|]
@ -54,7 +55,7 @@ getUsersR = do
E.orderBy [E.asc $ school E.^. SchoolShorthand]
return $ school E.^. SchoolShorthand
return [whamlet|
<ul>
<ul .list--inline .list--comma-separated>
$forall (E.Value sh) <- schools
<li>#{sh}
|]
@ -95,7 +96,15 @@ postAdminHijackUserR cID = do
case hijackRes of
FormSuccess uid'
| uid' == uid -> do
User{..} <- runDB $ get404 uid
myUid <- requireAuthId
User{..} <- runDB $ do
otherSchoolsAdmin <- Set.fromList . map (userAdminSchool . entityVal) <$> selectList [UserAdminUser ==. uid] []
otherSchoolsLecturer <- Set.fromList . map (userLecturerSchool . entityVal) <$> selectList [UserLecturerUser ==. uid] []
mySchools <- Set.fromList . map (userAdminSchool . entityVal) <$> selectList [UserAdminUser ==. myUid] []
when (not $ (otherSchoolsAdmin `Set.union` otherSchoolsLecturer) `Set.isSubsetOf` mySchools) $
permissionDenied "Cannot escalate admin status to additional schools"
get404 uid
setCredsRedirect $ Creds "dummy" (userPlugin <> ":" <> userIdent) []
| otherwise -> error "This should be impossible by definition of `hijackUserForm`"
FormFailure errs -> toTypedContent <$> mapM_ (addMessage "error" . toHtml) errs

View File

@ -8,10 +8,10 @@
Der Handler sollte jeweils aktuelle Beispiele für alle möglichen Funktionalitäten enthalten, so dass man immer weiß, wo man nachschlagen kann.
<div .container>
<div .container.js-show-hide>
<h2 .js-show-hide__toggle>Teilweise funktionierende Abschnitte
<ul>
<ul .js-show-hide__target>
<li .list-group-item>
<a href=@{UsersR}>Benutzer Verwaltung

View File

@ -115,10 +115,6 @@ ul {
list-style-type: none;
}
.list--inline > li {
display: inline-block;
}
h1, h2, h3, h4, h5 {
font-weight: 600;
}
@ -214,14 +210,14 @@ h4 {
@media (max-width: 768px) {
.main__content-body {
padding: 0 20px 60px;
padding: 30px 20px 60px;
}
}
@media (max-width: 425px) {
.main__content-body {
padding: 0 10px 60px;
padding: 20px 10px 60px;
}
}
@ -422,6 +418,22 @@ input[type="button"].btn-info:hover,
line-height: 25px;
}
/* LIST MODIFIERS */
.list--inline > li {
display: inline-block;
}
.list--comma-separated > li {
&::after {
content: ', ';
}
&:last-of-type::after {
content: none;
}
}
/* DEFINITION LIST */
.deflist {
display: grid;

View File

@ -11,7 +11,6 @@
autoDecay = parseInt(dataDecay, 10);
}
closeEl.classList.add('alert__close');
closeEl.innerText = #{String (messageRender MsgCloseAlert)};
closeEl.addEventListener('click', function(event) {
alertEl.classList.add('alert--invisible');
});

View File

@ -72,6 +72,7 @@
.alert {
margin-left: 80px;
max-width: 420px;
}
}

View File

@ -8,29 +8,45 @@
document.addEventListener('DOMContentLoaded', function() {
var elements = Array.from(document.querySelectorAll('.js-show-hide__toggle')),
toggles = [];
var LSNAME = 'SHOW_HIDE';
function addEventHandler(el) {
el.addEventListener('click', function elClickListener() {
var toggle = toggles[el.dataset.index];
toggle.collapsed = !toggle.collapsed;
toggle.parent.classList.toggle('js-show-hide--collapsed', toggle.collapsed);
var newState = el.parentElement.classList.toggle('js-show-hide--collapsed');
updateLSState(el.dataset.shIndex || null, newState);
});
}
elements.forEach(function(el, i) {
el.dataset.index = i;
var coll = el.dataset.collapsed === 'true';
if (coll) {
el.parentElement.classList.add('js-show-hide--collapsed')
function updateLSState(index, state) {
if (!index) {
return false;
}
Array.from(el.parentElement.children).forEach(function(el) {
if (!el.classList.contains('js-show-hide__toggle')) {
el.classList.add('js-show-hide__target');
}
});
toggles.push({index: i, collapsed: coll, parent: el.parentElement});
addEventHandler(el);
var lsData = fromLocalStorage();
lsData[index] = state;
window.localStorage.setItem(LSNAME, JSON.stringify(lsData));
}
function collapsedStateInLocalStorage(index) {
return fromLocalStorage()[index] || null;
}
function fromLocalStorage() {
return JSON.parse(window.localStorage.getItem(LSNAME)) || {};
}
Array
.from(document.querySelectorAll('.js-show-hide__toggle'))
.forEach(function(el) {
var index = el.dataset.shIndex || null;
el.parentElement.classList.toggle(
'js-show-hide--collapsed',
collapsedStateInLocalStorage(index) || el.dataset.collapsed === 'true'
);
Array.from(el.parentElement.children).forEach(function(el) {
if (!el.classList.contains('js-show-hide__toggle')) {
el.classList.add('js-show-hide__target');
}
});
addEventHandler(el);
});
});

View File

@ -2,14 +2,14 @@ $newline never
<aside .main__aside>
<div .asidenav>
$forall tid@TermIdentifier{..} <- favouriteTerms
<div .asidenav__box>
<h3 .asidenav__box-title.js-show-hide__toggle>
<div .asidenav__box.js-show-hide>
<h3 .asidenav__box-title.js-show-hide__toggle data-sh-index="#{display season}-#{year}">
$case season
$of Winter
_{MsgWinterTermShort year}
$of Summer
_{MsgSummerTermShort year}
<ul .asidenav__list>
<ul .asidenav__list.js-show-hide__target>
$forall (Course{..}, courseRoute, pageActions) <- favouriteTerm tid
<li .asidenav__list-item :highlight courseRoute:.asidenav__list-item--active>
<a .asidenav__link-wrapper href=@{courseRoute}>

View File

@ -19,15 +19,21 @@
document.addEventListener('DOMContentLoaded', function() {
var asidenavEl = document.querySelector('.main__aside');
var mainEl = document.querySelector('.main__content');
var mainContentEl = document.querySelector('.main__content');
asidenavEl.style.height = `${mainEl.clientHeight + 75}px`;
window.addEventListener('resize', function() {
function adjustHeight() {
window.requestAnimationFrame(function() {
asidenavEl.style.height = `${mainEl.clientHeight + 75}px`;
asidenavEl.style.height = mainContentEl.clientHeight + 'px';
});
});
}
// unbeknownst to the user (below the fold), this happes slightly delayed
// because of dynamic changes to the styles inside the main__content
setTimeout(function() {
adjustHeight();
}, 10);
window.addEventListener('resize', adjustHeight);
window.utils.aside(asidenavEl);

View File

@ -16,6 +16,13 @@
}
}
@media (max-width: 768px) {
.main__aside {
min-height: calc(100% - var(--header-height-collapsed));
}
}
@media (max-width: 425px) {
.main__aside {