feat(course-teaser): moved course teaser functionality to util
Moved course teaser js functionality to frontend util; removed css class course-teaser and course-teaser div id; moved styling of course teaser from colonnade.lucius to course-teaser.scss of util
This commit is contained in:
parent
48113ebee0
commit
c99a3c7009
37
frontend/src/utils/course-teaser/course-teaser.js
Normal file
37
frontend/src/utils/course-teaser/course-teaser.js
Normal file
@ -0,0 +1,37 @@
|
||||
import { Utility } from '../../core/utility';
|
||||
import './course-teaser.scss';
|
||||
|
||||
var COURSE_TEASER_INITIALIZED_CLASS = 'course-teaser--initialized';
|
||||
|
||||
var COURSE_TEASER_EXPANDED_CLASS = 'course-teaser__expanded';
|
||||
var COURSE_TEASER_CHEVRON_CLASS = 'course-teaser__chevron';
|
||||
|
||||
@Utility({
|
||||
selector: '[uw-course-teaser]',
|
||||
})
|
||||
export class CourseTeaser {
|
||||
|
||||
_element;
|
||||
|
||||
constructor(element) {
|
||||
if (!element) {
|
||||
throw new Error('CourseTeaser utility cannot be setup without an element!');
|
||||
}
|
||||
if (element.classList.contains(COURSE_TEASER_INITIALIZED_CLASS)) {
|
||||
return false;
|
||||
}
|
||||
this._element = element;
|
||||
element.addEventListener('click', e => this._onToggleExpand(e));
|
||||
}
|
||||
|
||||
_onToggleExpand(event) {
|
||||
var isLink = event.target.tagName.toLowerCase() === 'a';
|
||||
var isChevron = event.target.classList.contains(COURSE_TEASER_CHEVRON_CLASS);
|
||||
var isExpanded = event.target.classList.contains(COURSE_TEASER_EXPANDED_CLASS);
|
||||
|
||||
if ((!isExpanded && !isLink) || isChevron) {
|
||||
this._element.classList.toggle(COURSE_TEASER_EXPANDED_CLASS);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
8
frontend/src/utils/course-teaser/course-teaser.md
Normal file
8
frontend/src/utils/course-teaser/course-teaser.md
Normal file
@ -0,0 +1,8 @@
|
||||
# CourseTeaser
|
||||
|
||||
Handles expanding and collapsing single course teaser widgets on click.
|
||||
|
||||
## Example usage
|
||||
```html
|
||||
<div uw-course-teaser>
|
||||
```
|
||||
135
frontend/src/utils/course-teaser/course-teaser.scss
Normal file
135
frontend/src/utils/course-teaser/course-teaser.scss
Normal file
@ -0,0 +1,135 @@
|
||||
[uw-course-teaser] {
|
||||
display: grid;
|
||||
grid-gap: 5px 7px;
|
||||
grid-template-columns: 50px 120px 1fr;
|
||||
padding: 10px;
|
||||
/* background-color: var(--course-bg-color); */
|
||||
transition: background-color .1s ease-out;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--course-bg-color);
|
||||
}
|
||||
|
||||
+ [uw-course-teaser] {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* chevron */
|
||||
.course-teaser__chevron {
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: -8px;
|
||||
border-width: 0 3px 3px 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-color: var(--color-fontsec);
|
||||
border-style: solid;
|
||||
transform: rotate(45deg);
|
||||
transition: transform .2s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
/* semester */
|
||||
.course-teaser__semester {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
justify-self: end;
|
||||
font-size: 1.1rem;
|
||||
a {
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
}
|
||||
|
||||
/* shorthand */
|
||||
.course-teaser__shorthand {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
justify-self: end;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* title */
|
||||
.course-teaser__title {
|
||||
grid-column: 3;
|
||||
grid-row: 2;
|
||||
font-size: 1.2rem;
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
/* registration */
|
||||
.course-teaser__registration {
|
||||
grid-column: 4;
|
||||
grid-row: 2;
|
||||
justify-self: end;
|
||||
align-self: baseline;
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
/* school */
|
||||
.course-teaser__school-value {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
align-self: end;
|
||||
a {
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
}
|
||||
|
||||
/* description */
|
||||
.course-teaser__description {
|
||||
grid-column: 3;
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
/* subtitle */
|
||||
.course-teaser__lecturer-label,
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__school-label {
|
||||
grid-column: 2;
|
||||
justify-self: end;
|
||||
color: var(--color-fontsec);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* hidden in closed state */
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__duedate-value,
|
||||
.course-teaser__description,
|
||||
.course-teaser__registration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* registered courses */
|
||||
.course-teaser__registered {
|
||||
.course-teaser__registration {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* expanded courses */
|
||||
.course-teaser__expanded {
|
||||
max-height: 1000px;
|
||||
|
||||
.course-teaser__chevron::before {
|
||||
transform: translateY(7px) rotate(225deg);
|
||||
}
|
||||
|
||||
.course-teaser__school-label,
|
||||
.course-teaser__school-value,
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__duedate-value,
|
||||
.course-teaser__description {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@ import { InputUtils } from './inputs/inputs';
|
||||
import { MassInput } from './mass-input/mass-input';
|
||||
import { Modal } from './modal/modal';
|
||||
import { Tooltip } from './tooltips/tooltips';
|
||||
import { CourseTeaser } from './course-teaser/course-teaser';
|
||||
|
||||
export const Utils = [
|
||||
Alerts,
|
||||
@ -23,4 +24,5 @@ export const Utils = [
|
||||
Modal,
|
||||
ShowHide,
|
||||
Tooltip,
|
||||
CourseTeaser,
|
||||
];
|
||||
|
||||
@ -1035,14 +1035,13 @@ dbTable PSValidator{..} dbtable@DBTable{ dbtIdent = dbtIdent'@(toPathPiece -> db
|
||||
columnCount = olength64 $ getColonnade dbtColonnade
|
||||
in case dbsTemplate of
|
||||
DBSTCourse c l r s -> do
|
||||
wRows <- forM (zip [0..length rows] rows) $ \(cid, row') -> let
|
||||
wRows <- forM rows $ \row' -> let
|
||||
Course{..} = row' ^. c . _entityVal
|
||||
lecturerUsers = row' ^. l
|
||||
courseLecturers = userSurname . entityVal <$> lecturerUsers
|
||||
isRegistered = row' ^. r
|
||||
courseSchoolName = schoolName $ row' ^. s . _entityVal
|
||||
courseSemester = (termToText . unTermKey) courseTerm
|
||||
courseId = tshow cid
|
||||
in return $(widgetFile "table/course/course-teaser")
|
||||
|
||||
return $(widgetFile "table/course/colonnade")
|
||||
|
||||
@ -9,139 +9,3 @@
|
||||
.scrolltable {
|
||||
box-shadow: none!important;
|
||||
}
|
||||
|
||||
.course-teaser {
|
||||
display: grid;
|
||||
grid-gap: 5px 7px;
|
||||
grid-template-columns: 50px 120px 1fr;
|
||||
padding: 10px;
|
||||
/* background-color: var(--course-bg-color); */
|
||||
transition: background-color .1s ease-out;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--course-bg-color);
|
||||
}
|
||||
|
||||
+ .course-teaser {
|
||||
margin-top: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* chevron */
|
||||
.course-teaser__chevron {
|
||||
cursor: pointer;
|
||||
padding: 10px;
|
||||
grid-column: 1;
|
||||
grid-row: 2;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
|
||||
&::before {
|
||||
content: '';
|
||||
display: block;
|
||||
margin-top: -8px;
|
||||
border-width: 0 3px 3px 0;
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
border-color: var(--color-fontsec);
|
||||
border-style: solid;
|
||||
transform: rotate(45deg);
|
||||
transition: transform .2s ease-out;
|
||||
}
|
||||
}
|
||||
|
||||
/* semester */
|
||||
.course-teaser__semester {
|
||||
grid-column: 2;
|
||||
grid-row: 1;
|
||||
justify-self: end;
|
||||
font-size: 1.1rem;
|
||||
a {
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
}
|
||||
|
||||
/* shorthand */
|
||||
.course-teaser__shorthand {
|
||||
grid-column: 2;
|
||||
grid-row: 2;
|
||||
justify-self: end;
|
||||
font-size: 1.2rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
/* title */
|
||||
.course-teaser__title {
|
||||
grid-column: 3;
|
||||
grid-row: 2;
|
||||
font-size: 1.2rem;
|
||||
align-self: baseline;
|
||||
}
|
||||
|
||||
/* registration */
|
||||
.course-teaser__registration {
|
||||
grid-column: 4;
|
||||
grid-row: 2;
|
||||
justify-self: end;
|
||||
align-self: baseline;
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
/* school */
|
||||
.course-teaser__school-value {
|
||||
grid-column: 3;
|
||||
grid-row: 1;
|
||||
align-self: end;
|
||||
a {
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
}
|
||||
|
||||
/* description */
|
||||
.course-teaser__description {
|
||||
grid-column: 3;
|
||||
color: var(--color-fontsec);
|
||||
}
|
||||
|
||||
/* subtitle */
|
||||
.course-teaser__lecturer-label,
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__school-label {
|
||||
grid-column: 2;
|
||||
justify-self: end;
|
||||
color: var(--color-fontsec);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* hidden in closed state */
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__duedate-value,
|
||||
.course-teaser__description,
|
||||
.course-teaser__registration {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* registered courses */
|
||||
.course-teaser__registered {
|
||||
.course-teaser__registration {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
/* expanded courses */
|
||||
.course-teaser__expanded {
|
||||
max-height: 1000px;
|
||||
|
||||
.course-teaser__chevron::before {
|
||||
transform: translateY(7px) rotate(225deg);
|
||||
}
|
||||
|
||||
.course-teaser__school-label,
|
||||
.course-teaser__school-value,
|
||||
.course-teaser__duedate-label,
|
||||
.course-teaser__duedate-value,
|
||||
.course-teaser__description {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<div .course-teaser :isRegistered:.course-teaser__registered #courseteaser-#{courseId} tabindex='1'>
|
||||
<div uw-course-teaser :isRegistered:.course-teaser__registered tabindex='1'>
|
||||
<div .course-teaser__chevron>
|
||||
<div .course-teaser__semester>
|
||||
<a href=@{TermCourseListR courseTerm}>_{courseSemester}
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
var COURSE_TEASER_EXPANDED_CLASS = 'course-teaser__expanded';
|
||||
var COURSE_TEASER_CHEVRON_CLASS = 'course-teaser__chevron';
|
||||
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var courseTeaserId = #{String courseId};
|
||||
var courseTeaser = document.querySelector('#courseteaser-' + courseTeaserId);
|
||||
|
||||
courseTeaser.addEventListener('click', function(event) {
|
||||
var isLink = event.target.tagName.toLowerCase() === 'a';
|
||||
var isChevron = event.target.classList.contains(COURSE_TEASER_CHEVRON_CLASS);
|
||||
var isExpanded = courseTeaser.classList.contains(COURSE_TEASER_EXPANDED_CLASS);
|
||||
|
||||
if ((!isExpanded && !isLink) || isChevron) {
|
||||
courseTeaser.classList.toggle(COURSE_TEASER_EXPANDED_CLASS);
|
||||
}
|
||||
});
|
||||
|
||||
courseTeaser.addEventListener('keydown', function(event) {
|
||||
var eventKey = event.key;
|
||||
if (eventKey === ' ' || eventKey === 'Enter') {
|
||||
event.preventDefault();
|
||||
courseTeaser.classList.toggle(COURSE_TEASER_EXPANDED_CLASS);
|
||||
}
|
||||
});
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user