feat: improve navigation
This commit is contained in:
parent
51fc6dc541
commit
95ffda25b6
@ -160,7 +160,7 @@ h4
|
||||
--current-header-height: var(--header-height-collapsed)
|
||||
position: relative
|
||||
background-color: white
|
||||
transition: padding-left .2s ease-out, margin-top 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
transition: padding-left .2s ease-out, margin-top 0.2s ease
|
||||
margin-top: var(--current-header-height)
|
||||
margin-left: 0
|
||||
|
||||
@ -203,7 +203,7 @@ h4
|
||||
.main__content
|
||||
margin-left: var(--asidenav-width-md, 50px)
|
||||
|
||||
@media (min-width: 769px) and (min-height: 501px)
|
||||
@media (min-width: 769px)
|
||||
.main__content
|
||||
margin-left: var(--asidenav-width-lg, 20%)
|
||||
|
||||
@ -641,7 +641,7 @@ section
|
||||
.ribbon
|
||||
position: fixed
|
||||
top: calc(40px + var(--header-height))
|
||||
transition: all 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
transition: all 0.2s ease
|
||||
right: -63px
|
||||
transform: rotate(45deg)
|
||||
width: 250px
|
||||
@ -652,7 +652,7 @@ section
|
||||
font-size: 1.25rem
|
||||
line-height: 2em
|
||||
box-shadow: 0 0 3px rgba(0, 0, 0, 0.4)
|
||||
z-index: 19
|
||||
z-index: 21
|
||||
pointer-events: none
|
||||
|
||||
.navbar__container-radio:checked ~ &
|
||||
@ -1003,9 +1003,12 @@ th, td
|
||||
.breadcrumbs__container
|
||||
position: relative
|
||||
color: var(--color-lightwhite)
|
||||
padding: 4px 13px 4px 40px
|
||||
padding: 4px 20px 4px 40px
|
||||
background-color: var(--color-dark)
|
||||
line-height: 30px
|
||||
margin: 0 -5px
|
||||
|
||||
a
|
||||
color: var(--color-lightwhite)
|
||||
|
||||
@media (min-width: 426px)
|
||||
.breadcrumbs__container
|
||||
@ -1015,45 +1018,31 @@ th, td
|
||||
.breadcrumbs__container
|
||||
padding: 7px 40px
|
||||
|
||||
.breadcrumbs__link
|
||||
color: var(--color-lightwhite)
|
||||
ul.breadcrumbs__list
|
||||
display: flex
|
||||
align-items: center
|
||||
height: 30px
|
||||
|
||||
&:hover
|
||||
color: var(--color-white)
|
||||
& > li
|
||||
display: block
|
||||
|
||||
.breadcrumbs__item
|
||||
padding-right: 14px
|
||||
position: relative
|
||||
line-height: 28px
|
||||
opacity: 0.8
|
||||
z-index: 1
|
||||
margin-right: 10px
|
||||
margin: 0 5px
|
||||
|
||||
&:hover
|
||||
opacity: 1
|
||||
|
||||
&::after
|
||||
content: ''
|
||||
position: absolute
|
||||
top: 5.5px
|
||||
right: 0
|
||||
width: 7px
|
||||
height: 7px
|
||||
border-style: solid
|
||||
border-width: 0
|
||||
border-bottom-width: 1px
|
||||
border-right-width: 1px
|
||||
border-color: var(--color-white)
|
||||
transform: rotate(-45deg)
|
||||
z-index: 10
|
||||
|
||||
@media (min-width: 426px)
|
||||
top: 11px
|
||||
.breadcrumbs__item-separator
|
||||
line-height: 0
|
||||
opacity: 0.5
|
||||
margin: 0 5px
|
||||
margin-top: 1px
|
||||
|
||||
a.breadcrumbs__home
|
||||
position: absolute
|
||||
left: 10px
|
||||
top: 8px
|
||||
left: 15px
|
||||
top: 5px
|
||||
width: 20px
|
||||
height: 30px
|
||||
opacity: 0.5
|
||||
@ -1061,14 +1050,16 @@ a.breadcrumbs__home
|
||||
color: var(--color-lightwhite)
|
||||
text-align: center
|
||||
line-height: 30px
|
||||
|
||||
@media (min-width: 426px)
|
||||
top: 8px
|
||||
|
||||
&:hover
|
||||
opacity: 1
|
||||
|
||||
.breadcrumbs__last-item
|
||||
line-height: 28px
|
||||
vertical-align: bottom
|
||||
font-weight: 600
|
||||
opacity: 1
|
||||
|
||||
.recipient-category
|
||||
max-width: 400px
|
||||
@ -1144,7 +1135,7 @@ a.breadcrumbs__home
|
||||
text-align: center
|
||||
padding: 20px
|
||||
position: relative
|
||||
margin: 40px 0
|
||||
margin: 40px 0 0 0
|
||||
|
||||
&::before
|
||||
content: ''
|
||||
@ -1183,70 +1174,3 @@ a.breadcrumbs__home
|
||||
.checkbox
|
||||
display: inline-block
|
||||
margin-left: 7px
|
||||
|
||||
.pagenav
|
||||
display: flex
|
||||
align-items: flex-start
|
||||
padding-bottom: 15px
|
||||
margin-bottom: 20px
|
||||
border-bottom: 1px solid #eee
|
||||
|
||||
.pagenav__list-item
|
||||
flex: 1
|
||||
position: relative
|
||||
display: inline-flex
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
margin: 10px 10px 0 0
|
||||
|
||||
.pagenav__link-wrapper
|
||||
flex: 1
|
||||
padding: 10px 10px 12px
|
||||
text-decoration: none !important
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
@media (max-width: 1024px)
|
||||
.pagenav
|
||||
flex-direction: column
|
||||
|
||||
@media (min-width: 1025px)
|
||||
.pagenav-secondary
|
||||
position: relative
|
||||
overflow: visible
|
||||
padding-top: 10px
|
||||
|
||||
&::after
|
||||
content: '\2026'
|
||||
display: inline-block
|
||||
padding: 10px 10px 12px
|
||||
width: 40px
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
box-sizing: border-box
|
||||
text-align: center
|
||||
transition: box-shadow 0.2s ease
|
||||
|
||||
&:hover
|
||||
&::after
|
||||
box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.8)
|
||||
|
||||
.pagenav-secondary__list
|
||||
display: block
|
||||
|
||||
.pagenav-secondary__list
|
||||
position: absolute
|
||||
display: none
|
||||
right: 0
|
||||
top: 50px
|
||||
width: 250px
|
||||
background-color: white
|
||||
box-shadow: 0 0 6px 3px var(--color-grey-light)
|
||||
z-index: 18
|
||||
|
||||
.pagenav__list-item--secondary
|
||||
display: flex
|
||||
box-shadow: none
|
||||
margin: 0
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
@ -58,7 +58,7 @@ export class UtilRegistry {
|
||||
if (utilInstance) {
|
||||
const instance = utilInstance.instance;
|
||||
if (instance && typeof instance.start === 'function') {
|
||||
instance.start();
|
||||
instance.start.bind(instance)();
|
||||
startedInstances.push(instance);
|
||||
}
|
||||
}
|
||||
@ -91,6 +91,7 @@ export class UtilRegistry {
|
||||
if (DEBUG_MODE > 0) {
|
||||
console.error('Error while trying to initialize a utility!', { util , element, err });
|
||||
}
|
||||
utilInstance = null;
|
||||
}
|
||||
|
||||
if (utilInstance) {
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
.main__aside
|
||||
position: fixed
|
||||
box-shadow: 0 0 10px rgba(0, 0, 0, 0.3)
|
||||
z-index: 1
|
||||
top: 0
|
||||
left: 0
|
||||
width: var(--asidenav-width-lg, 20%)
|
||||
@ -9,16 +8,7 @@
|
||||
flex: 0 0 0
|
||||
flex-basis: var(--asidenav-width-lg, 20%)
|
||||
transition: all .2s ease-out
|
||||
|
||||
&::before
|
||||
position: absolute
|
||||
z-index: -1
|
||||
left: 0
|
||||
top: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
background-color: var(--color-dark)
|
||||
opacity: 0.05
|
||||
z-index: 20
|
||||
|
||||
&::after
|
||||
content: ''
|
||||
@ -233,7 +223,7 @@
|
||||
// hover sub-menus
|
||||
.asidenav__nested-list-wrapper
|
||||
position: absolute
|
||||
z-index: 10
|
||||
z-index: 22
|
||||
display: none
|
||||
color: var(--color-font)
|
||||
background-color: var(--color-grey-light)
|
||||
@ -270,6 +260,10 @@
|
||||
min-height: calc(100% - var(--header-height-collapsed))
|
||||
top: var(--header-height-collapsed)
|
||||
|
||||
.navbar__container-radio:checked ~ &
|
||||
min-height: calc(100% - var(--header-height-collapsed) - 30px)
|
||||
top: calc(var(--header-height-collapsed) + 30px)
|
||||
|
||||
.asidenav__box-title
|
||||
width: var(--asidenav-width-md, 50px)
|
||||
font-size: 18px
|
||||
@ -278,6 +272,7 @@
|
||||
word-break: break-all
|
||||
background-color: var(--color-dark)
|
||||
color: var(--color-lightwhite)
|
||||
border: none
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-darker)
|
||||
|
||||
@ -3,7 +3,7 @@ import './navbar.sass';
|
||||
import * as throttle from 'lodash.throttle';
|
||||
|
||||
export const HEADER_CONTAINER_UTIL_SELECTOR = '.navbar__list-item--container-selector .navbar__link-wrapper';
|
||||
const HEADER_CONTAINER_INITIALIZED_CLASS = '.navbar-header-container--initialized';
|
||||
const HEADER_CONTAINER_INITIALIZED_CLASS = 'navbar-header-container--initialized';
|
||||
|
||||
@Utility({
|
||||
selector: HEADER_CONTAINER_UTIL_SELECTOR,
|
||||
@ -24,7 +24,7 @@ export class NavHeaderContainerUtil {
|
||||
}
|
||||
|
||||
if (element.classList.contains(HEADER_CONTAINER_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
this._element = element;
|
||||
@ -55,6 +55,9 @@ export class NavHeaderContainerUtil {
|
||||
}
|
||||
|
||||
start() {
|
||||
if (!this.container)
|
||||
return;
|
||||
|
||||
window.addEventListener('click', this.clickHandler.bind(this));
|
||||
this.radioButton.addEventListener('change', this.throttleUpdateWasOpen.bind(this));
|
||||
}
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
min-height: var(--header-height)
|
||||
background-color: var(--color-primary)
|
||||
color: white
|
||||
z-index: 20
|
||||
z-index: 22
|
||||
box-shadow: 0 0 4px rgba(0, 0, 0, 0.2)
|
||||
overflow: auto
|
||||
transition: all 0.2s cubic-bezier(0.03, 0.43, 0.58, 1)
|
||||
@ -64,6 +64,7 @@
|
||||
|
||||
.navbar__container-list
|
||||
/* margin: 10px 0 0 0 */
|
||||
position: relative
|
||||
padding: 0 40px
|
||||
overflow: hidden
|
||||
display: flex
|
||||
@ -108,8 +109,6 @@
|
||||
|
||||
transform-origin: 10px 10px
|
||||
transform: rotate(-0.25turn)
|
||||
&.navbar__container-list--left
|
||||
transform: rotate(0.25turn)
|
||||
|
||||
opacity: 0.5
|
||||
transition: transform 0.2s, opacity 0.2s ease
|
||||
@ -126,9 +125,12 @@
|
||||
visibility: hidden
|
||||
|
||||
&.navbar__container-list--left .navbar__container-list-closer
|
||||
left: 14.5px
|
||||
transform: rotate(0.25turn)
|
||||
right: auto
|
||||
left: 10px
|
||||
|
||||
&:hover
|
||||
transform: scale(1.4)
|
||||
|
||||
// links
|
||||
.navbar__link-wrapper
|
||||
|
||||
110
frontend/src/utils/pageactions/pageactions.js
Normal file
110
frontend/src/utils/pageactions/pageactions.js
Normal file
@ -0,0 +1,110 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './pageactions.sass';
|
||||
import * as throttle from 'lodash.throttle';
|
||||
|
||||
export const PAGEACTION_SECONDARY_UTIL_SELECTOR = '.pagenav__list-item';
|
||||
const PAGEACTION_SECONDARY_INITIALIZED_CLASS = '.pagenav-list-item--initialized';
|
||||
const PAGEACTION_SECONDARY_CLASS = 'pagenav-secondary';
|
||||
|
||||
@Utility({
|
||||
selector: PAGEACTION_SECONDARY_UTIL_SELECTOR,
|
||||
})
|
||||
export class PageActionSecondaryUtil {
|
||||
_element;
|
||||
navIdent;
|
||||
radioButton;
|
||||
closeButton;
|
||||
container;
|
||||
wasOpen;
|
||||
|
||||
_throttleUpdateWasOpen;
|
||||
|
||||
constructor(element) {
|
||||
if (!element) {
|
||||
throw new Error('Pageaction Secondary utility needs to be passed an element!');
|
||||
}
|
||||
|
||||
if (element.classList.contains(PAGEACTION_SECONDARY_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
this._element = element;
|
||||
|
||||
const childContainer = this._element.querySelector('.pagenav-item__children');
|
||||
|
||||
if (!childContainer) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._element.classList.contains(PAGEACTION_SECONDARY_CLASS)) {
|
||||
this.navIdent = 'secondary';
|
||||
} else {
|
||||
const links = Array.from(this._element.querySelectorAll('.pagenav-item__link')).filter(l => !childContainer.contains(l));
|
||||
|
||||
if (!links || Array.from(links).length !== 1) {
|
||||
throw new Error('Pageaction Secondary utility could not find associated link!');
|
||||
}
|
||||
this.navIdent = links[0].id;
|
||||
}
|
||||
|
||||
this.radioButton = document.getElementById(`pageaction-item__expand-${this.navIdent}`);
|
||||
if (!this.radioButton) {
|
||||
throw new Error('Pageaction Secondary utility could not find associated radio button!');
|
||||
}
|
||||
|
||||
this.closeButton = document.getElementById('pageaction-item__expand-none');
|
||||
if (!this.closeButton) {
|
||||
throw new Error('Pageaction Secondary utility could not find radio button for closing!');
|
||||
}
|
||||
|
||||
this.container = document.querySelector('.pagenav-item__children-wrapper');
|
||||
if (!this.container) {
|
||||
throw new Error('Pageaction Secondary utility could not find associated container!');
|
||||
}
|
||||
|
||||
const closer = this._element.querySelector('.pagenav-item__close-label');
|
||||
if (closer) {
|
||||
closer.classList.add('pagenav-item__close-label--hidden');
|
||||
}
|
||||
|
||||
this.updateWasOpen();
|
||||
this.throttleUpdateWasOpen = throttle(this.updateWasOpen.bind(this), 100, { leading: false, trailing: true });
|
||||
|
||||
this._element.classList.add(PAGEACTION_SECONDARY_INITIALIZED_CLASS);
|
||||
}
|
||||
|
||||
start() {
|
||||
if (!this.container)
|
||||
return;
|
||||
|
||||
window.addEventListener('click', this.clickHandler.bind(this));
|
||||
this.radioButton.addEventListener('change', this.throttleUpdateWasOpen.bind(this));
|
||||
}
|
||||
|
||||
clickHandler() {
|
||||
if (!this.container.contains(event.target) && window.document.contains(event.target) && this.wasOpen) {
|
||||
this.close();
|
||||
}
|
||||
}
|
||||
|
||||
close() {
|
||||
this.radioButton.checked = false;
|
||||
this.throttleUpdateWasOpen();
|
||||
}
|
||||
|
||||
isOpen() {
|
||||
return this.radioButton.checked;
|
||||
}
|
||||
|
||||
updateWasOpen() {
|
||||
this.wasOpen = this.isOpen();
|
||||
}
|
||||
|
||||
destroy() { /* TODO */ }
|
||||
}
|
||||
|
||||
|
||||
|
||||
export const PageActionsUtils = [
|
||||
PageActionSecondaryUtil,
|
||||
];
|
||||
190
frontend/src/utils/pageactions/pageactions.sass
Normal file
190
frontend/src/utils/pageactions/pageactions.sass
Normal file
@ -0,0 +1,190 @@
|
||||
|
||||
.pagenav
|
||||
display: flex
|
||||
align-content: flex-start
|
||||
align-items: flex-start
|
||||
flex-flow: row wrap
|
||||
padding: 0 0 10px 0
|
||||
margin: -5px -5px 20px -5px
|
||||
border-bottom: 1px solid #eee
|
||||
list-style: none
|
||||
|
||||
.pagenav-item__expand-radio
|
||||
display: none
|
||||
|
||||
.pagenav-item__link
|
||||
display: block
|
||||
padding: 6px 10px
|
||||
background-color: white
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
a.pagenav-item__link, .pagenav-item__link a
|
||||
text-decoration: none
|
||||
|
||||
.pagenav__list-item
|
||||
position: relative
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
margin: 5px
|
||||
padding: 0
|
||||
display: grid
|
||||
grid-template-areas: "label expand"
|
||||
grid-template-columns: auto minmax(0, auto)
|
||||
flex: 0 0 auto
|
||||
|
||||
& > *
|
||||
grid-area: label
|
||||
place-self: stretch / stretch
|
||||
line-height: 20px
|
||||
|
||||
&.pagenav-item__children-wrapper
|
||||
grid-column: label-start / expand-end
|
||||
|
||||
& > .pagenav-item__expand-label
|
||||
display: flex
|
||||
justify-content: center
|
||||
align-items: center
|
||||
grid-area: expand
|
||||
background-color: white
|
||||
transition: background-color 0.2s ease
|
||||
padding: 6px 10px
|
||||
cursor: pointer
|
||||
|
||||
.fas
|
||||
line-height: 20px
|
||||
|
||||
&:hover
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.9)
|
||||
|
||||
& > .pagenav-item__expand-label
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
.pagenav-item__link:hover ~ .pagenav-item__expand-label
|
||||
background-color: white
|
||||
|
||||
.pagenav-item__expand-radio:checked ~ .pagenav-item__expand-label
|
||||
background-color: var(--color-grey-light)
|
||||
|
||||
.pagenav-secondary &
|
||||
grid-template-areas: "expand"
|
||||
& > .pagenav-item__children-wrapper
|
||||
grid-column: exand-start / exand-end
|
||||
|
||||
|
||||
.pagenav-item__children
|
||||
flex: 1 0 auto
|
||||
list-style: none
|
||||
margin: 0
|
||||
padding: 0
|
||||
display: grid
|
||||
grid-template-rows: auto
|
||||
justify-items: stretch
|
||||
grid-auto-columns: max-content
|
||||
|
||||
.pagenav-item__link
|
||||
max-width: 250px
|
||||
|
||||
& > li
|
||||
display: flex
|
||||
|
||||
& > *
|
||||
flex: 1 0 auto
|
||||
|
||||
.pagenav-item__close-label
|
||||
display: none
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
padding: 6px 10px
|
||||
transition: all 0.2s ease
|
||||
position: absolute
|
||||
top: 100%
|
||||
right: 0
|
||||
background-color: white
|
||||
z-index: -1
|
||||
cursor: pointer
|
||||
|
||||
.fas
|
||||
transition: all 0.2s ease
|
||||
opacity: 0.5
|
||||
transform: rotate(0.5turn)
|
||||
line-height: 20px
|
||||
|
||||
&:hover
|
||||
background-color: var(--color-grey-light)
|
||||
.fas
|
||||
transform: rotate(0)
|
||||
opacity: 1
|
||||
|
||||
.pagenav-item__children-wrapper
|
||||
display: none
|
||||
position: absolute
|
||||
right: 0
|
||||
top: 100%
|
||||
background-color: white
|
||||
z-index: 21
|
||||
margin: 0
|
||||
padding: 0
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
|
||||
.pagenav-item__expand-radio:checked ~ &, .pagenav-item__expand-label:hover ~ &, &:hover
|
||||
display: flex
|
||||
|
||||
.pagenav__list-item:hover &
|
||||
box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.9)
|
||||
|
||||
.pagenav-item__expand-radio:checked ~ &
|
||||
.pagenav-item__close-label:not(.pagenav-item__close-label--hidden)
|
||||
display: block
|
||||
|
||||
/* .pagenav__link-wrapper
|
||||
/* flex: 1
|
||||
/* padding: 10px 10px 12px
|
||||
/* text-decoration: none !important
|
||||
|
||||
/* &:hover
|
||||
/* background-color: var(--color-grey-light)
|
||||
|
||||
/* @media (max-width: 1024px)
|
||||
/* .pagenav
|
||||
/* flex-direction: column
|
||||
|
||||
/* @media (min-width: 1025px)
|
||||
/* .pagenav-secondary
|
||||
/* position: relative
|
||||
/* overflow: visible
|
||||
/* padding-top: 10px
|
||||
|
||||
/* &::after
|
||||
/* content: '\2026'
|
||||
/* display: inline-block
|
||||
/* padding: 10px 10px 12px
|
||||
/* width: 40px
|
||||
/* box-shadow: 0 0 2px 0 rgba(0, 0, 0, 0.6)
|
||||
/* box-sizing: border-box
|
||||
/* text-align: center
|
||||
/* transition: box-shadow 0.2s ease
|
||||
|
||||
/* &:hover
|
||||
/* &::after
|
||||
/* box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.8)
|
||||
|
||||
/* .pagenav-secondary__list
|
||||
/* display: block
|
||||
|
||||
/* .pagenav-secondary__list
|
||||
/* position: absolute
|
||||
/* display: none
|
||||
/* right: 0
|
||||
/* top: 50px
|
||||
/* width: 250px
|
||||
/* background-color: white
|
||||
/* box-shadow: 0 0 6px 3px var(--color-grey-light)
|
||||
/* z-index: 18
|
||||
|
||||
/* .pagenav__list-item--secondary
|
||||
/* display: flex
|
||||
/* box-shadow: none
|
||||
/* margin: 0
|
||||
|
||||
/* &:hover
|
||||
/* background-color: var(--color-grey-light)
|
||||
@ -11,6 +11,7 @@ import { Modal } from './modal/modal';
|
||||
import { Tooltip } from './tooltips/tooltips';
|
||||
import { CourseTeaser } from './course-teaser/course-teaser';
|
||||
import { NavbarUtils } from './navbar/navbar';
|
||||
import { PageActionsUtils } from './pageactions/pageactions';
|
||||
import { HideColumns } from './hide-columns/hide-columns';
|
||||
|
||||
export const Utils = [
|
||||
@ -28,5 +29,6 @@ export const Utils = [
|
||||
Tooltip,
|
||||
CourseTeaser,
|
||||
...NavbarUtils,
|
||||
...PageActionsUtils,
|
||||
HideColumns,
|
||||
];
|
||||
|
||||
13
records.json
13
records.json
@ -765,5 +765,18 @@
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
],
|
||||
"mini-css-extract-plugin node_modules/css-loader/dist/cjs.js??ref--6-1!node_modules/postcss-loader/src/index.js??ref--6-2!node_modules/resolve-url-loader/index.js??ref--6-3!node_modules/sass-loader/dist/cjs.js??ref--6-4!frontend/src/utils/pageactions/pageactions.sass": [
|
||||
{
|
||||
"modules": {
|
||||
"byIdentifier": {},
|
||||
"usedIds": {}
|
||||
},
|
||||
"chunks": {
|
||||
"byName": {},
|
||||
"bySource": {},
|
||||
"usedIds": []
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -78,7 +78,7 @@ import Handler.Utils.ExamOffice.ExternalExam
|
||||
import Handler.Utils.Profile
|
||||
import Handler.Utils.Routes
|
||||
import Utils.Form
|
||||
-- import Utils.Sheet
|
||||
import Utils.Sheet
|
||||
import Utils.SystemMessage
|
||||
|
||||
import Text.Shakespeare.Text (st)
|
||||
@ -117,6 +117,16 @@ instance RenderMessage UniWorX (UnsupportedAuthPredicate AuthTag (Route UniWorX)
|
||||
mr = renderMessage f ls
|
||||
(pieces, _) = renderRoute route
|
||||
|
||||
data NavQuickView
|
||||
= NavQuickViewFavourite
|
||||
| NavQuickViewPageActionSecondary
|
||||
deriving (Eq, Ord, Enum, Bounded, Read, Show, Generic, Typeable)
|
||||
instance Universe NavQuickView
|
||||
instance Finite NavQuickView
|
||||
|
||||
navQuick :: NavQuickView -> (NavQuickView -> Any)
|
||||
navQuick x x' = Any $ x == x'
|
||||
|
||||
data NavType
|
||||
= NavTypeLink
|
||||
{ navModal :: Bool
|
||||
@ -140,7 +150,7 @@ data NavLink = forall msg route. (RenderMessage UniWorX msg, HasRoute UniWorX ro
|
||||
, navRoute :: route
|
||||
, navAccess' :: Handler Bool
|
||||
, navType :: NavType
|
||||
, navQuick :: Bool
|
||||
, navQuick' :: NavQuickView -> Any
|
||||
, navForceActive :: Bool
|
||||
}
|
||||
|
||||
@ -1670,9 +1680,7 @@ siteLayout' headingOverride widget = do
|
||||
-> let courseRoute = CourseR courseTerm courseSchool courseShorthand CShowR
|
||||
favouriteReason = fromMaybe FavouriteCurrent mFavourite
|
||||
in do
|
||||
items''' <- pageActions courseRoute
|
||||
items'' <- catMaybes <$> mapM (runMaybeT . navAccess) items'''
|
||||
items' <- filterM navLinkAccess $ items'' ^.. typesUsing @NavChildren @NavLink . filtered navQuick
|
||||
items' <- pageQuickActions NavQuickViewFavourite courseRoute
|
||||
items <- forM items' $ \n -> (n,) <$> toTextUrl n
|
||||
return (c, courseRoute, items, favouriteReason)
|
||||
|
||||
@ -1720,7 +1728,7 @@ siteLayout' headingOverride widget = do
|
||||
-- you to use normal widget features in default-layout.
|
||||
|
||||
navWidget :: (Nav, Text, Maybe Text, [(NavLink, Text, Text)]) -> Widget
|
||||
navWidget (n, navIdent, navRoute', _navChildren') = case n of
|
||||
navWidget (n, navIdent, navRoute', navChildren') = case n of
|
||||
NavHeader{ navLink = navLink@NavLink{..}, .. }
|
||||
| NavTypeLink{..} <- navType
|
||||
, navModal
|
||||
@ -1735,18 +1743,24 @@ siteLayout' headingOverride widget = do
|
||||
ident = navIdent
|
||||
in $(widgetFile "widgets/navbar/item")
|
||||
NavPageActionPrimary{ navLink = navLink@NavLink{..}, .. }
|
||||
| NavTypeLink{..} <- navType
|
||||
, navModal
|
||||
-> customModal Modal
|
||||
{ modalTriggerId = Just navIdent
|
||||
, modalId = Nothing
|
||||
, modalTrigger = \(Just route) ident -> $(widgetFile "widgets/pageaction/primary")
|
||||
, modalContent = Left $ SomeRoute navLink
|
||||
}
|
||||
| NavTypeLink{} <- navType
|
||||
-> let route = navRoute'
|
||||
ident = navIdent
|
||||
in $(widgetFile "widgets/pageaction/primary")
|
||||
-> let pWidget
|
||||
| NavTypeLink{..} <- navType
|
||||
, navModal
|
||||
= customModal Modal
|
||||
{ modalTriggerId = Just navIdent
|
||||
, modalId = Nothing
|
||||
, modalTrigger = \(Just route) ident -> $(widgetFile "widgets/pageaction/primary")
|
||||
, modalContent = Left $ SomeRoute navLink
|
||||
}
|
||||
| NavTypeLink{} <- navType
|
||||
= let route = navRoute'
|
||||
ident = navIdent
|
||||
in $(widgetFile "widgets/pageaction/primary")
|
||||
| otherwise
|
||||
= error "not implemented"
|
||||
sWidgets = navChildren'
|
||||
& map (\(l, i, r) -> navWidget (NavPageActionSecondary l, i, Just r, []))
|
||||
in $(widgetFile "widgets/pageaction/primary-wrapper")
|
||||
NavPageActionSecondary{ navLink = navLink@NavLink{..}, .. }
|
||||
| NavTypeLink{..} <- navType
|
||||
, navModal
|
||||
@ -1821,10 +1835,13 @@ siteLayout' headingOverride widget = do
|
||||
hasPageActions = hasPrimaryPageActions || hasSecondaryPageActions
|
||||
hasSecondaryPageActions = has (folded . _1 . _NavPageActionSecondary) nav
|
||||
hasPrimaryPageActions = has (folded . _1 . _NavPageActionPrimary ) nav
|
||||
hasPrimarySubActions = has (folded . _1 . filtered (is _NavPageActionPrimary) . _navChildren . folded) nav
|
||||
contentRibbon :: Maybe Widget
|
||||
contentRibbon = fmap toWidget appRibbon
|
||||
|
||||
isNavHeaderContainer = has $ _1 . _NavHeaderContainer
|
||||
isPageActionPrimary = has $ _1 . _NavPageActionPrimary
|
||||
isPageActionSecondary = has $ _1 . _NavPageActionSecondary
|
||||
|
||||
MsgRenderer mr <- getMsgRenderer
|
||||
let
|
||||
@ -2171,7 +2188,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = AuthR LogoutR
|
||||
, navAccess' = is _Just <$> maybeAuthId
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2183,7 +2200,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = AuthR LoginR
|
||||
, navAccess' = is _Nothing <$> maybeAuthId
|
||||
, navType = NavTypeLink { navModal = True }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2195,7 +2212,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = ProfileR
|
||||
, navAccess' = is _Just <$> maybeAuthId
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2212,7 +2229,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
{ navMethod = POST
|
||||
, navData = [(toPathPiece PostLanguage, lang)]
|
||||
}
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = lang == activeLang
|
||||
}
|
||||
|
||||
@ -2235,7 +2252,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = (HelpR, [(toPathPiece GetReferer, toPathPiece currentRoute) | let Just currentRoute = mCurrentRoute ])
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = True }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2244,7 +2261,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = LegalR :#: ("data-protection" :: Text)
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, return $ NavFooter NavLink
|
||||
@ -2252,7 +2269,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = LegalR :#: ("terms-of-use" :: Text)
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, return $ NavFooter NavLink
|
||||
@ -2260,7 +2277,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = LegalR :#: ("copyright" :: Text)
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, return $ NavFooter NavLink
|
||||
@ -2268,7 +2285,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = LegalR :#: ("imprint" :: Text)
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, return $ NavFooter NavLink
|
||||
@ -2276,7 +2293,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = InfoR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, return $ NavFooter NavLink
|
||||
@ -2284,7 +2301,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = GlossaryR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, return NavHeader
|
||||
@ -2295,7 +2312,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = NewsR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2307,7 +2324,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = CourseListR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2319,7 +2336,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = CorrectionsR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2331,7 +2348,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = ExamOfficeR EOExamsR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
}
|
||||
@ -2345,7 +2362,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = UsersR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2353,7 +2370,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = SchoolListR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2361,7 +2378,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = AdminFeaturesR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2369,7 +2386,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = MessageListR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2377,7 +2394,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = AdminErrMsgR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2385,7 +2402,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = AdminTestR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
]
|
||||
@ -2400,7 +2417,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = CourseNewR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2408,7 +2425,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = EExamListR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2416,7 +2433,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = TermShowR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2424,7 +2441,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = AllocationListR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, NavLink
|
||||
@ -2432,7 +2449,7 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
, navRoute = InfoLecturerR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick = False
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
]
|
||||
@ -2440,26 +2457,267 @@ defaultLinks = fmap catMaybes . mapM runMaybeT $ -- Define the menu items of the
|
||||
]
|
||||
|
||||
|
||||
-- pageActions :: (MonadHandler m, HandlerSite m ~ UniWorX) => Route UniWorX -> m [Nav]
|
||||
pageActions :: _
|
||||
pageActions :: ( MonadHandler m
|
||||
, HandlerSite m ~ UniWorX
|
||||
, MonadCatch m
|
||||
)
|
||||
=> Route UniWorX -> m [Nav]
|
||||
pageActions NewsR = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuOpenCourses
|
||||
, navRoute = (CourseListR, [("courses-openregistration", toPathPiece True)])
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = []
|
||||
}
|
||||
, NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuOpenAllocations
|
||||
, navRoute = (AllocationListR, [("allocations-active", toPathPiece True)])
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = []
|
||||
}
|
||||
]
|
||||
pageActions (CourseR tid ssh csh CShowR) = do
|
||||
sheetListSecondary <- pageQuickActions NavQuickViewPageActionSecondary $ CourseR tid ssh csh SheetListR
|
||||
|
||||
return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuMaterialList
|
||||
, navRoute = CourseR tid ssh csh MaterialListR
|
||||
, navAccess' =
|
||||
let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh MaterialNewR -- Always show for lecturers to create new material
|
||||
materialAccess mnm = hasReadAccessTo $ CMaterialR tid ssh csh mnm MShowR -- otherwise show only if the user can see at least one of the contents
|
||||
existsVisible = do
|
||||
matNames <- E.select . E.from $ \(course `E.InnerJoin` material) -> do
|
||||
E.on $ course E.^. CourseId E.==. material E.^. MaterialCourse
|
||||
E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
return $ material E.^. MaterialName
|
||||
anyM matNames (materialAccess . E.unValue)
|
||||
in runDB $ lecturerAccess `or2M` existsVisible
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = navQuick NavQuickViewFavourite
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = [] -- TODO: MaterialNewR
|
||||
}
|
||||
, NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuSheetList
|
||||
, navRoute = CourseR tid ssh csh SheetListR
|
||||
, navAccess' =
|
||||
let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh SheetNewR -- Always show for lecturers to create new sheets
|
||||
sheetAccess shn = hasReadAccessTo $ CSheetR tid ssh csh shn SShowR -- othwerwise show only if the user can see at least one of the contents
|
||||
existsVisible = do
|
||||
sheetNames <- E.select . E.from $ \(course `E.InnerJoin` sheet) -> do
|
||||
E.on $ course E.^. CourseId E.==. sheet E.^. SheetCourse
|
||||
E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
return $ sheet E.^. SheetName
|
||||
anyM sheetNames $ sheetAccess . E.unValue
|
||||
in runDB $ lecturerAccess `or2M` existsVisible
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = navQuick NavQuickViewFavourite
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = sheetListSecondary
|
||||
}
|
||||
, NavPageActionSecondary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuCourseDelete
|
||||
, navRoute = CourseR tid ssh csh CDeleteR
|
||||
, navAccess' = return True
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = mempty
|
||||
, navForceActive = False
|
||||
}
|
||||
} -- TODO
|
||||
]
|
||||
pageActions (CourseR tid ssh csh SheetListR) = return
|
||||
[ NavPageActionPrimary
|
||||
{ navLink = NavLink
|
||||
{ navLabel = MsgMenuSheetCurrent
|
||||
, navRoute = CourseR tid ssh csh SheetCurrentR
|
||||
, navAccess' = runDB . maybeT (return False) $
|
||||
True <$ MaybeT (sheetCurrent tid ssh csh)
|
||||
, navType = NavTypeLink { navModal = False }
|
||||
, navQuick' = navQuick NavQuickViewFavourite <> navQuick NavQuickViewPageActionSecondary
|
||||
, navForceActive = False
|
||||
}
|
||||
, navChildren = []
|
||||
} -- TODO
|
||||
]
|
||||
pageActions _ = return []
|
||||
-- pageActions (NewsR) =
|
||||
-- pageActions (CourseR tid ssh csh CShowR) =
|
||||
-- [ MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuOpenCourses
|
||||
-- , menuItemLabel = MsgMenuMaterialList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute (CourseListR, [("courses-openregistration", "True")])
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh MaterialListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh MaterialNewR -- Always show for lecturers to create new material
|
||||
-- materialAccess mnm = hasReadAccessTo $ CMaterialR tid ssh csh mnm MShowR -- otherwise show only if the user can see at least one of the contents
|
||||
-- existsVisible = do
|
||||
-- matNames <- E.select . E.from $ \(course `E.InnerJoin` material) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. material E.^. MaterialCourse
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- return $ material E.^. MaterialName
|
||||
-- anyM matNames (materialAccess . E.unValue)
|
||||
-- in runDB $ lecturerAccess `or2M` existsVisible
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuSheetList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh SheetListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh SheetNewR -- Always show for lecturers to create new sheets
|
||||
-- sheetAccess shn = hasReadAccessTo $ CSheetR tid ssh csh shn SShowR -- othwerwise show only if the user can see at least one of the contents
|
||||
-- existsVisible = do
|
||||
-- sheetNames <- E.select . E.from $ \(course `E.InnerJoin` sheet) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. sheet E.^. SheetCourse
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- return $ sheet E.^. SheetName
|
||||
-- anyM sheetNames $ sheetAccess . E.unValue
|
||||
-- in runDB $ lecturerAccess `or2M` existsVisible
|
||||
-- }
|
||||
-- ] ++ pageActions (CourseR tid ssh csh SheetListR) ++
|
||||
-- [ MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuTutorialList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CTutorialListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuOpenAllocations
|
||||
-- , menuItemLabel = MsgMenuExamList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute (AllocationListR, [("allocations-active", "True")])
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CExamListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh CExamNewR
|
||||
-- examAccess examn = hasReadAccessTo $ CExamR tid ssh csh examn EShowR
|
||||
-- existsVisible = do
|
||||
-- examNames <- E.select . E.from $ \(course `E.InnerJoin` exam) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- return $ exam E.^. ExamName
|
||||
-- anyM examNames $ examAccess . E.unValue
|
||||
-- in runDB $ lecturerAccess `or2M` existsVisible
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseApplications
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CApplicationsR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let courseWhere course = course <$ do
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- existsApplications = E.selectExists . E.from $ \(course `E.InnerJoin` courseApplication) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. courseApplication E.^. CourseApplicationCourse
|
||||
-- void $ courseWhere course
|
||||
-- courseApplications = fmap (any E.unValue) . E.select . E.from $ \course -> do
|
||||
-- void $ courseWhere course
|
||||
-- return $ course E.^. CourseApplicationsRequired
|
||||
-- courseAllocation = E.selectExists . E.from $ \(course `E.InnerJoin` allocationCourse) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. allocationCourse E.^. AllocationCourseCourse
|
||||
-- void $ courseWhere course
|
||||
-- in runDB $ courseAllocation `or2M` courseApplications `or2M` existsApplications
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseMembers
|
||||
-- , menuItemIcon = Just "user-graduate"
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CUsersR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = do
|
||||
-- now <- liftIO getCurrentTime
|
||||
-- let courseWhere course = course <$ do
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- hasActiveAllocation = E.selectExists . E.from $ \(course `E.InnerJoin` allocationCourse `E.InnerJoin` allocation) -> do
|
||||
-- E.on $ allocation E.^. AllocationId E.==. allocationCourse E.^. AllocationCourseAllocation
|
||||
-- E.on $ allocationCourse E.^. AllocationCourseCourse E.==. course E.^. CourseId
|
||||
-- void $ courseWhere course
|
||||
-- E.where_ $ E.maybe E.false (E.<=. E.val now) (allocation E.^. AllocationRegisterByStaffFrom)
|
||||
-- E.||. E.maybe E.false (E.<=. E.val now) (allocation E.^. AllocationRegisterByCourse)
|
||||
-- hasParticipants = E.selectExists . E.from $ \(course `E.InnerJoin` courseParticipant) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. courseParticipant E.^. CourseParticipantCourse
|
||||
-- void $ courseWhere course
|
||||
-- runDB $ (not <$> hasActiveAllocation) `or2M` hasParticipants
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseCommunication
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CCommR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseEdit
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CEditR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseClone
|
||||
-- , menuItemIcon = Just "copy"
|
||||
-- , menuItemRoute = SomeRoute (CourseNewR, [("tid", toPathPiece tid), ("ssh", toPathPiece ssh), ("csh", toPathPiece csh)])
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseDelete
|
||||
-- , menuItemIcon = Just "trash"
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CDeleteR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseExamOffice
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CExamOfficeR
|
||||
-- , menuItemModal = True
|
||||
-- , menuItemAccessCallback' = do
|
||||
-- uid <- requireAuthId
|
||||
-- runDB $ do
|
||||
-- cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
||||
-- E.selectExists $ do
|
||||
-- (_school, isForced) <- courseExamOfficeSchools (E.val uid) (E.val cid)
|
||||
-- E.where_ $ E.not_ isForced
|
||||
-- }
|
||||
-- ]
|
||||
-- pageActions (AdminR) =
|
||||
-- [ MenuItem
|
||||
@ -2746,165 +3004,6 @@ pageActions _ = return []
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- ]
|
||||
-- pageActions (CourseR tid ssh csh CShowR) =
|
||||
-- [ MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuMaterialList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh MaterialListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh MaterialNewR -- Always show for lecturers to create new material
|
||||
-- materialAccess mnm = hasReadAccessTo $ CMaterialR tid ssh csh mnm MShowR -- otherwise show only if the user can see at least one of the contents
|
||||
-- existsVisible = do
|
||||
-- matNames <- E.select . E.from $ \(course `E.InnerJoin` material) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. material E.^. MaterialCourse
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- return $ material E.^. MaterialName
|
||||
-- anyM matNames (materialAccess . E.unValue)
|
||||
-- in runDB $ lecturerAccess `or2M` existsVisible
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuSheetList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh SheetListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh SheetNewR -- Always show for lecturers to create new sheets
|
||||
-- sheetAccess shn = hasReadAccessTo $ CSheetR tid ssh csh shn SShowR -- othwerwise show only if the user can see at least one of the contents
|
||||
-- existsVisible = do
|
||||
-- sheetNames <- E.select . E.from $ \(course `E.InnerJoin` sheet) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. sheet E.^. SheetCourse
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- return $ sheet E.^. SheetName
|
||||
-- anyM sheetNames $ sheetAccess . E.unValue
|
||||
-- in runDB $ lecturerAccess `or2M` existsVisible
|
||||
-- }
|
||||
-- ] ++ pageActions (CourseR tid ssh csh SheetListR) ++
|
||||
-- [ MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuTutorialList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CTutorialListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
-- , menuItemLabel = MsgMenuExamList
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CExamListR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let lecturerAccess = hasWriteAccessTo $ CourseR tid ssh csh CExamNewR
|
||||
-- examAccess examn = hasReadAccessTo $ CExamR tid ssh csh examn EShowR
|
||||
-- existsVisible = do
|
||||
-- examNames <- E.select . E.from $ \(course `E.InnerJoin` exam) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. exam E.^. ExamCourse
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- return $ exam E.^. ExamName
|
||||
-- anyM examNames $ examAccess . E.unValue
|
||||
-- in runDB $ lecturerAccess `or2M` existsVisible
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseApplications
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CApplicationsR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' =
|
||||
-- let courseWhere course = course <$ do
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- existsApplications = E.selectExists . E.from $ \(course `E.InnerJoin` courseApplication) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. courseApplication E.^. CourseApplicationCourse
|
||||
-- void $ courseWhere course
|
||||
-- courseApplications = fmap (any E.unValue) . E.select . E.from $ \course -> do
|
||||
-- void $ courseWhere course
|
||||
-- return $ course E.^. CourseApplicationsRequired
|
||||
-- courseAllocation = E.selectExists . E.from $ \(course `E.InnerJoin` allocationCourse) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. allocationCourse E.^. AllocationCourseCourse
|
||||
-- void $ courseWhere course
|
||||
-- in runDB $ courseAllocation `or2M` courseApplications `or2M` existsApplications
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseMembers
|
||||
-- , menuItemIcon = Just "user-graduate"
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CUsersR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = do
|
||||
-- now <- liftIO getCurrentTime
|
||||
-- let courseWhere course = course <$ do
|
||||
-- E.where_ $ course E.^. CourseTerm E.==. E.val tid
|
||||
-- E.&&. course E.^. CourseSchool E.==. E.val ssh
|
||||
-- E.&&. course E.^. CourseShorthand E.==. E.val csh
|
||||
-- hasActiveAllocation = E.selectExists . E.from $ \(course `E.InnerJoin` allocationCourse `E.InnerJoin` allocation) -> do
|
||||
-- E.on $ allocation E.^. AllocationId E.==. allocationCourse E.^. AllocationCourseAllocation
|
||||
-- E.on $ allocationCourse E.^. AllocationCourseCourse E.==. course E.^. CourseId
|
||||
-- void $ courseWhere course
|
||||
-- E.where_ $ E.maybe E.false (E.<=. E.val now) (allocation E.^. AllocationRegisterByStaffFrom)
|
||||
-- E.||. E.maybe E.false (E.<=. E.val now) (allocation E.^. AllocationRegisterByCourse)
|
||||
-- hasParticipants = E.selectExists . E.from $ \(course `E.InnerJoin` courseParticipant) -> do
|
||||
-- E.on $ course E.^. CourseId E.==. courseParticipant E.^. CourseParticipantCourse
|
||||
-- void $ courseWhere course
|
||||
-- runDB $ (not <$> hasActiveAllocation) `or2M` hasParticipants
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseCommunication
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CCommR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseEdit
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CEditR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseClone
|
||||
-- , menuItemIcon = Just "copy"
|
||||
-- , menuItemRoute = SomeRoute (CourseNewR, [("tid", toPathPiece tid), ("ssh", toPathPiece ssh), ("csh", toPathPiece csh)])
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseDelete
|
||||
-- , menuItemIcon = Just "trash"
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CDeleteR
|
||||
-- , menuItemModal = False
|
||||
-- , menuItemAccessCallback' = return True
|
||||
-- }
|
||||
-- , MenuItem
|
||||
-- { menuItemType = PageActionSecondary
|
||||
-- , menuItemLabel = MsgMenuCourseExamOffice
|
||||
-- , menuItemIcon = Nothing
|
||||
-- , menuItemRoute = SomeRoute $ CourseR tid ssh csh CExamOfficeR
|
||||
-- , menuItemModal = True
|
||||
-- , menuItemAccessCallback' = do
|
||||
-- uid <- requireAuthId
|
||||
-- runDB $ do
|
||||
-- cid <- getKeyBy404 $ TermSchoolCourseShort tid ssh csh
|
||||
-- E.selectExists $ do
|
||||
-- (_school, isForced) <- courseExamOfficeSchools (E.val uid) (E.val cid)
|
||||
-- E.where_ $ E.not_ isForced
|
||||
-- }
|
||||
-- ]
|
||||
-- pageActions (CourseR tid ssh csh CCorrectionsR) =
|
||||
-- [ MenuItem
|
||||
-- { menuItemType = PageActionPrime
|
||||
@ -3464,6 +3563,16 @@ pageActions _ = return []
|
||||
-- ]
|
||||
-- pageActions _ = []
|
||||
|
||||
pageQuickActions :: ( MonadCatch m
|
||||
, MonadHandler m
|
||||
, HandlerSite m ~ UniWorX
|
||||
)
|
||||
=> NavQuickView -> Route UniWorX -> m [NavLink]
|
||||
pageQuickActions qView route = do
|
||||
items'' <- pageActions route
|
||||
items' <- catMaybes <$> mapM (runMaybeT . navAccess) items''
|
||||
filterM navLinkAccess $ items' ^.. typesUsing @NavChildren @NavLink . filtered (getAny . ($ qView) . navQuick')
|
||||
|
||||
|
||||
i18nHeading :: (MonadWidget m, RenderMessage site msg, HandlerSite m ~ site) => msg -> m ()
|
||||
i18nHeading msg = liftWidget $ toWidget =<< getMessageRender <*> pure msg
|
||||
|
||||
@ -69,7 +69,7 @@ data Icon
|
||||
| IconNotificationError
|
||||
| IconFavourite
|
||||
| IconLanguage
|
||||
| IconNavContainerClose
|
||||
| IconNavContainerClose | IconPageActionChildrenClose
|
||||
| IconMenuNews
|
||||
| IconMenuHelp
|
||||
| IconMenuProfile
|
||||
@ -80,62 +80,68 @@ data Icon
|
||||
| IconMenuCorrections
|
||||
| IconMenuExams
|
||||
| IconMenuAdmin
|
||||
| IconPageActionPrimaryExpand | IconPageActionSecondary
|
||||
| IconBreadcrumbSeparator
|
||||
deriving (Eq, Ord, Enum, Bounded, Show, Read, Generic, Typeable)
|
||||
|
||||
iconText :: Icon -> Text
|
||||
iconText = \case
|
||||
IconNew -> "seedling"
|
||||
IconOK -> "check"
|
||||
IconNotOK -> "times"
|
||||
IconWarning -> "exclamation"
|
||||
IconProblem -> "bolt"
|
||||
IconVisible -> "eye"
|
||||
IconInvisible -> "eye-slash"
|
||||
IconCourse -> "graduation-cap"
|
||||
IconEnrolTrue -> "user-plus"
|
||||
IconEnrolFalse -> "user-slash"
|
||||
IconPlanned -> "cog"
|
||||
IconAnnounce -> "bullhorn"
|
||||
IconExam -> "poll-h"
|
||||
IconExamRegisterTrue -> "calendar-check"
|
||||
IconExamRegisterFalse -> "calendar-times"
|
||||
IconCommentTrue -> "comment-alt"
|
||||
IconCommentFalse -> "comment-alt-slash"
|
||||
IconLink -> "link"
|
||||
IconFileDownload -> "file-download"
|
||||
IconFileUpload -> "file-upload"
|
||||
IconFileZip -> "file-archive"
|
||||
IconFileCSV -> "file-csv"
|
||||
IconSFTQuestion -> "question-circle" -- for SheetFileType only, should all be round (similar)
|
||||
IconSFTHint -> "life-ring" -- for SheetFileType only
|
||||
IconSFTSolution -> "exclamation-circle" -- for SheetFileType only
|
||||
IconSFTMarking -> "check-circle" -- for SheetFileType only
|
||||
IconEmail -> "envelope"
|
||||
IconRegisterTemplate -> "file-alt"
|
||||
IconApplyTrue -> "file-alt"
|
||||
IconApplyFalse -> "trash"
|
||||
IconNoCorrectors -> "user-slash"
|
||||
IconApplicationVeto -> "times"
|
||||
IconApplicationFiles -> "file-alt"
|
||||
IconTooltipDefault -> "question-circle"
|
||||
IconNotificationSuccess -> "check-circle"
|
||||
IconNotificationInfo -> "info-circle"
|
||||
IconNotificationWarning -> "exclamation-circle"
|
||||
IconNotificationError -> "exclamation-triangle"
|
||||
IconFavourite -> "star"
|
||||
IconLanguage -> "flag-alt"
|
||||
IconNavContainerClose -> "chevron-up"
|
||||
IconMenuNews -> "megaphone"
|
||||
IconMenuHelp -> "question"
|
||||
IconMenuProfile -> "cogs"
|
||||
IconMenuLogin -> "sign-in-alt"
|
||||
IconMenuLogout -> "sign-out-alt"
|
||||
IconBreadcrumbsHome -> "home"
|
||||
IconMenuExtra -> "ellipsis-h"
|
||||
IconMenuCourseList -> "graduation-cap"
|
||||
IconMenuCorrections -> "check"
|
||||
IconMenuExams -> "poll-h"
|
||||
IconMenuAdmin -> "screwdriver"
|
||||
IconNew -> "seedling"
|
||||
IconOK -> "check"
|
||||
IconNotOK -> "times"
|
||||
IconWarning -> "exclamation"
|
||||
IconProblem -> "bolt"
|
||||
IconVisible -> "eye"
|
||||
IconInvisible -> "eye-slash"
|
||||
IconCourse -> "graduation-cap"
|
||||
IconEnrolTrue -> "user-plus"
|
||||
IconEnrolFalse -> "user-slash"
|
||||
IconPlanned -> "cog"
|
||||
IconAnnounce -> "bullhorn"
|
||||
IconExam -> "poll-h"
|
||||
IconExamRegisterTrue -> "calendar-check"
|
||||
IconExamRegisterFalse -> "calendar-times"
|
||||
IconCommentTrue -> "comment-alt"
|
||||
IconCommentFalse -> "comment-alt-slash"
|
||||
IconLink -> "link"
|
||||
IconFileDownload -> "file-download"
|
||||
IconFileUpload -> "file-upload"
|
||||
IconFileZip -> "file-archive"
|
||||
IconFileCSV -> "file-csv"
|
||||
IconSFTQuestion -> "question-circle" -- for SheetFileType only, should all be round (similar)
|
||||
IconSFTHint -> "life-ring" -- for SheetFileType only
|
||||
IconSFTSolution -> "exclamation-circle" -- for SheetFileType only
|
||||
IconSFTMarking -> "check-circle" -- for SheetFileType only
|
||||
IconEmail -> "envelope"
|
||||
IconRegisterTemplate -> "file-alt"
|
||||
IconApplyTrue -> "file-alt"
|
||||
IconApplyFalse -> "trash"
|
||||
IconNoCorrectors -> "user-slash"
|
||||
IconApplicationVeto -> "times"
|
||||
IconApplicationFiles -> "file-alt"
|
||||
IconTooltipDefault -> "question-circle"
|
||||
IconNotificationSuccess -> "check-circle"
|
||||
IconNotificationInfo -> "info-circle"
|
||||
IconNotificationWarning -> "exclamation-circle"
|
||||
IconNotificationError -> "exclamation-triangle"
|
||||
IconFavourite -> "star"
|
||||
IconLanguage -> "flag-alt"
|
||||
IconNavContainerClose -> "chevron-up"
|
||||
IconPageActionChildrenClose -> "chevron-up"
|
||||
IconMenuNews -> "megaphone"
|
||||
IconMenuHelp -> "question"
|
||||
IconMenuProfile -> "cogs"
|
||||
IconMenuLogin -> "sign-in-alt"
|
||||
IconMenuLogout -> "sign-out-alt"
|
||||
IconBreadcrumbsHome -> "home"
|
||||
IconMenuExtra -> "ellipsis-h"
|
||||
IconMenuCourseList -> "graduation-cap"
|
||||
IconMenuCorrections -> "check"
|
||||
IconMenuExams -> "poll-h"
|
||||
IconMenuAdmin -> "screwdriver"
|
||||
IconPageActionPrimaryExpand -> "bars"
|
||||
IconPageActionSecondary -> "ellipsis-h"
|
||||
IconBreadcrumbSeparator -> "angle-right"
|
||||
|
||||
instance Universe Icon
|
||||
instance Finite Icon
|
||||
|
||||
@ -32,7 +32,7 @@ $if not isModal
|
||||
<a .breadcrumbs__link href="@{fst back}">#{snd back} -->
|
||||
^{headline}
|
||||
|
||||
$if not isModal && hasPageActions
|
||||
$if hasPageActions
|
||||
<!-- page actions -->
|
||||
^{pageaction}
|
||||
|
||||
|
||||
@ -6,7 +6,12 @@ $newline never
|
||||
$forall (bcRoute, bcTitle, hasAccess) <- parents
|
||||
<li .breadcrumbs__item>
|
||||
$if hasAccess
|
||||
<a .breadcrumbs__link href="@{bcRoute}">#{bcTitle}
|
||||
<a .breadcrumbs__link href="@{bcRoute}">
|
||||
#{bcTitle}
|
||||
$else
|
||||
<span .breadcrumbs__link>#{bcTitle}
|
||||
<li .breadcrumbs__last-item>#{title}
|
||||
<span .breadcrumbs__link>
|
||||
#{bcTitle}
|
||||
<li .breadcrumbs__item-separator>
|
||||
#{iconBreadcrumbSeparator}
|
||||
<li .breadcrumbs__item .breadcrumbs__last-item>
|
||||
#{title}
|
||||
|
||||
@ -1,13 +1,19 @@
|
||||
$newline never
|
||||
<div .pagenav>
|
||||
$if hasPrimaryPageActions
|
||||
<div .pagenav-prime>
|
||||
$forall n@(NavPageActionPrimary{}, _, _, _) <- nav
|
||||
<div .pagenav__list-item>
|
||||
^{navWidget n}
|
||||
$if hasSecondaryPageActions || hasPrimarySubActions
|
||||
<input .pagenav-item__expand-radio name=pagenav-item__expand-radio id=pageaction-item__expand-none type=radio checked>
|
||||
<ul .pagenav>
|
||||
$forall n <- filter isPageActionPrimary nav
|
||||
<li .pagenav__list-item>
|
||||
^{navWidget n}
|
||||
$if hasSecondaryPageActions
|
||||
<div .pagenav-secondary>
|
||||
<div .pagenav-secondary__list>
|
||||
$forall n@(NavPageActionPrimary{}, _, _, _) <- nav
|
||||
<div .pagenav__list-item.pagenav__list-item--secondary>
|
||||
^{navWidget n}
|
||||
<li .pagenav__list-item .pagenav-secondary>
|
||||
<input .pagenav-item__expand-radio name=pagenav-item__expand-radio id=pageaction-item__expand-secondary type=radio>
|
||||
<label .pagenav-item__expand-label for=pageaction-item__expand-secondary>
|
||||
<i .fas .fa-fw .fa-#{iconText IconPageActionSecondary}>
|
||||
<div .pagenav-item__children-wrapper>
|
||||
<ul .pagenav-item__children>
|
||||
$forall n <- filter isPageActionSecondary nav
|
||||
<li>
|
||||
^{navWidget n}
|
||||
<label .pagenav-item__close-label for=pageaction-item__expand-none>
|
||||
#{iconPageActionChildrenClose}
|
||||
|
||||
13
templates/widgets/pageaction/primary-wrapper.hamlet
Normal file
13
templates/widgets/pageaction/primary-wrapper.hamlet
Normal file
@ -0,0 +1,13 @@
|
||||
$newline never
|
||||
^{pWidget}
|
||||
$if not (null sWidgets)
|
||||
<input .pagenav-item__expand-radio name=pagenav-item__expand-radio id=pageaction-item__expand-#{navIdent} type=radio>
|
||||
<label .pagenav-item__expand-label for=pageaction-item__expand-#{navIdent}>
|
||||
<i .fas .fa-fw .fa-#{iconText IconPageActionPrimaryExpand}>
|
||||
<div .pagenav-item__children-wrapper>
|
||||
<ul .pagenav-item__children>
|
||||
$forall sWgt <- sWidgets
|
||||
<li>
|
||||
^{sWgt}
|
||||
<label .pagenav-item__close-label for=pageaction-item__expand-none>
|
||||
#{iconPageActionChildrenClose}
|
||||
@ -1,2 +1,3 @@
|
||||
$newline never
|
||||
<a .pagenav__link-wrapper href=#{route} ##{ident}>_{SomeMessage navLabel}
|
||||
<a .pagenav-item__link href=#{route} ##{ident}>
|
||||
_{SomeMessage navLabel}
|
||||
|
||||
@ -1,2 +1,3 @@
|
||||
$newline never
|
||||
<a .pagenav__link-wrapper.pagenav__link-wrapper--secondary href=#{route} ##{ident}>_{SomeMessage navLabel}
|
||||
<a .pagenav-item__link href=#{route} ##{ident}>
|
||||
_{SomeMessage navLabel}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user