From f99c8b3b86348d62f70e266687d053afbd408ab8 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Tue, 10 Apr 2018 21:54:12 +0200 Subject: [PATCH 01/20] include credentials in ajax-call --- templates/table/colonnade.julius | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/templates/table/colonnade.julius b/templates/table/colonnade.julius index 840cccd6a..fcea7dea9 100644 --- a/templates/table/colonnade.julius +++ b/templates/table/colonnade.julius @@ -23,8 +23,8 @@ 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'); + // TODO: make use of dbtIdent instead of -terms- + url.searchParams.set('terms-table-only', 'true'); updateTableFrom(url); markSorted(this.parentNode, order); } @@ -40,6 +40,7 @@ // 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' } From 08607a5e7c99bd1abbcef845de96b0ad49dc0741 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Wed, 11 Apr 2018 14:28:33 +0200 Subject: [PATCH 02/20] Fix javascript issues, 'directions' in sortable-header, sorted attrs --- src/Handler/Utils/Table/Pagination.hs | 8 +++++++- templates/table/colonnade.julius | 3 +-- templates/table/sortable-header.hamlet | 13 ++++++++++--- 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/Handler/Utils/Table/Pagination.hs b/src/Handler/Utils/Table/Pagination.hs index ef3ab45ec..776fd3498 100644 --- a/src/Handler/Utils/Table/Pagination.hs +++ b/src/Handler/Utils/Table/Pagination.hs @@ -153,10 +153,16 @@ dbTable PSValidator{..} DBTable{ dbtIdent = (toPathPiece -> dbtIdent), .. } = do let table = $(widgetFile "table/colonnade") pageCount = max 1 . ceiling $ rowCount % psLimit tblLink f = decodeUtf8 . Builder.toLazyByteString . renderQueryText True $ f getParams + withSortLinks Sortable{ sortableContent = Cell{..}, .. } = Cell { cellContents = $(widgetFile "table/sortable-header") - , .. + , cellAttrs = maybe mempty (const sortableAttr) sortableKey <> cellAttrs } + where + directions = [dir | (k, dir) <- psSorting, Just k == sortableKey ] + sortableAttr = foldMap toAttr directions + toAttr SortAsc = Html5.class_ "sorted-asc" + toAttr SortDesc = Html5.class_ "sorted-desc" $(widgetFile "table/layout") where tblLayout :: Widget -> Handler Html diff --git a/templates/table/colonnade.julius b/templates/table/colonnade.julius index fcea7dea9..212ecf4ff 100644 --- a/templates/table/colonnade.julius +++ b/templates/table/colonnade.julius @@ -23,8 +23,7 @@ event.preventDefault(); var url = new URL(window.location.origin + window.location.pathname + this.getAttribute('href')); var order = this.parentNode.dataset.order || ASC; - // TODO: make use of dbtIdent instead of -terms- - url.searchParams.set('terms-table-only', 'true'); + url.searchParams.set(#{String $ wIdent "table-only"}, 'yes'); updateTableFrom(url); markSorted(this.parentNode, order); } diff --git a/templates/table/sortable-header.hamlet b/templates/table/sortable-header.hamlet index 1054b1ce0..b5e006b6a 100644 --- a/templates/table/sortable-header.hamlet +++ b/templates/table/sortable-header.hamlet @@ -1,7 +1,14 @@ ^{cellContents} $maybe flag <- sortableKey
- "-asc")}>asc - / - "-desc")}>desc + $case directions + $of [SortAsc] + "-desc")}>desc + $of [SortDesc] + "-asc")}>asc + $of [] + "-desc")}>desc + / + "-asc")}>asc + $of _ $nothing From 3047dfe9f2d5fb924a125899dda8fa23972b41da Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Wed, 11 Apr 2018 14:34:17 +0200 Subject: [PATCH 03/20] Use psShortcircuit in colonnade.hamlet --- templates/table/colonnade.hamlet | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/templates/table/colonnade.hamlet b/templates/table/colonnade.hamlet index ef6b1bdbd..90951ce7c 100644 --- a/templates/table/colonnade.hamlet +++ b/templates/table/colonnade.hamlet @@ -1,10 +1,17 @@ - - $maybe sortableP <- pSortable - $with toSortable <- toSortable sortableP - - $forall OneColonnade{..} <- getColonnade dbtColonnade - ^{widgetFromCell th $ withSortLinks $ toSortable oneColonnadeHead} - $nothing +$if not psShortcircuit +
+ $maybe sortableP <- pSortable + $with toSortable <- toSortable sortableP + + $forall OneColonnade{..} <- getColonnade dbtColonnade + ^{widgetFromCell th $ withSortLinks $ toSortable oneColonnadeHead} + $nothing + + $forall row <- rows + + $forall OneColonnade{..} <- getColonnade dbtColonnade + ^{widgetFromCell td $ oneColonnadeEncode row} +$else $forall row <- rows From 73d535d8c3a7b976146865b34809e36ae47a3833 Mon Sep 17 00:00:00 2001 From: Gregor Kleen Date: Wed, 11 Apr 2018 14:37:39 +0200 Subject: [PATCH 04/20] =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- templates/table/colonnade.hamlet | 9 ++++----- templates/table/layout.hamlet | 13 ++++++++----- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/templates/table/colonnade.hamlet b/templates/table/colonnade.hamlet index 90951ce7c..b109dd442 100644 --- a/templates/table/colonnade.hamlet +++ b/templates/table/colonnade.hamlet @@ -12,8 +12,7 @@ $if not psShortcircuit $forall OneColonnade{..} <- getColonnade dbtColonnade ^{widgetFromCell td $ oneColonnadeEncode row} $else - - $forall row <- rows - - $forall OneColonnade{..} <- getColonnade dbtColonnade - ^{widgetFromCell td $ oneColonnadeEncode row} + $forall row <- rows + + $forall OneColonnade{..} <- getColonnade dbtColonnade + ^{widgetFromCell td $ oneColonnadeEncode row} diff --git a/templates/table/layout.hamlet b/templates/table/layout.hamlet index 009e4eb2c..eb5651cb3 100644 --- a/templates/table/layout.hamlet +++ b/templates/table/layout.hamlet @@ -1,6 +1,9 @@ -
+$if not psShortcircuit +
+ ^{table} + $if pageCount > 1 +

+ $# TODO: foreach (reachable pages) print link to that page + _{MsgPage (succ psPage) pageCount} +$else ^{table} - $if pageCount > 1 -

- $# TODO: foreach (reachable pages) print link to that page - _{MsgPage (succ psPage) pageCount} From 6441b8dbefda276849b6b86734f164a9c3048e70 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Wed, 11 Apr 2018 21:46:33 +0200 Subject: [PATCH 05/20] solution for more-than-three-characters course-shorthands --- templates/widgets/asidenav.lucius | 41 ++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/templates/widgets/asidenav.lucius b/templates/widgets/asidenav.lucius index 1f7e26ba5..acda69bd3 100644 --- a/templates/widgets/asidenav.lucius +++ b/templates/widgets/asidenav.lucius @@ -28,6 +28,22 @@ .asidenav__link-wrapper { .asidenav__link-shorthand { display: flex; + position: static; + background-color: var(--darkbase); + color: var(--whitebase); + height: 50px; + width: 50px; + text-align: center; + opacity: 1; + font-size: 16px; + line-height: 1em; + margin-right: 13px; + flex-shrink: 0; + outline: 1px solid white; + text-transform: uppercase; + word-break: break-all; + align-items: center; + justify-content: center; } .asidenav__link-label { padding-left: 0; @@ -123,8 +139,8 @@ } .asidenav__link-shorthand { - background-color: var(--whitebase); - color: var(--darkbase); + transform: scale(1.05, 1.0); + transform-origin: right; } } } @@ -152,19 +168,16 @@ } .asidenav__link-shorthand { - background-color: var(--darkbase); - color: var(--whitebase); - height: 50px; - width: 50px; - display: none; - text-align: center; - margin-right: 13px; - flex-shrink: 0; - outline: 1px solid white; + display: block; + position: absolute; + color: var(--greybase); + line-height: 50px; + opacity: 0.3; + right: 10px; + top: 0; + font-size: 40px; text-transform: uppercase; - word-break: break-all; - align-items: center; - justify-content: center; + transition: transform .2s ease; } .asidenav__link-label { From dd7f9f51bf2be325d450fd51146e08d4a1c91a09 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Wed, 11 Apr 2018 21:55:12 +0200 Subject: [PATCH 06/20] fixed nested lists in asidenav to trigger early --- templates/widgets/asidenav.lucius | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/templates/widgets/asidenav.lucius b/templates/widgets/asidenav.lucius index acda69bd3..62c2d3f0c 100644 --- a/templates/widgets/asidenav.lucius +++ b/templates/widgets/asidenav.lucius @@ -92,7 +92,9 @@ color: var(--fontbase); transform: translateX(0); opacity: 0; - transition: all .2s ease; + transition: all .2s ease-out; + width: 0; + overflow: hidden; z-index: -1; .asidenav__list-item { @@ -131,6 +133,7 @@ .asidenav__nested-list { transform: translateX(100%); opacity: 1; + width: 200px; } .asidenav__link-wrapper, From 796f4d08321c6d70c712b03becdb75c8581dd8ad Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Thu, 12 Apr 2018 00:37:54 +0200 Subject: [PATCH 07/20] clickable ths for toggling of sort-direction --- templates/table/colonnade.hamlet | 30 ++++------ templates/table/colonnade.julius | 61 -------------------- templates/table/layout.hamlet | 14 ++--- templates/table/layout.julius | 79 ++++++++++++++++++++++++++ templates/table/sortable-header.hamlet | 2 - templates/terms.hamlet | 3 +- 6 files changed, 98 insertions(+), 91 deletions(-) delete mode 100644 templates/table/colonnade.julius create mode 100644 templates/table/layout.julius diff --git a/templates/table/colonnade.hamlet b/templates/table/colonnade.hamlet index b109dd442..ef6b1bdbd 100644 --- a/templates/table/colonnade.hamlet +++ b/templates/table/colonnade.hamlet @@ -1,18 +1,12 @@ -$if not psShortcircuit -

- $maybe sortableP <- pSortable - $with toSortable <- toSortable sortableP - - $forall OneColonnade{..} <- getColonnade dbtColonnade - ^{widgetFromCell th $ withSortLinks $ toSortable oneColonnadeHead} - $nothing - - $forall row <- rows - - $forall OneColonnade{..} <- getColonnade dbtColonnade - ^{widgetFromCell td $ oneColonnadeEncode row} -$else - $forall row <- rows - - $forall OneColonnade{..} <- getColonnade dbtColonnade - ^{widgetFromCell td $ oneColonnadeEncode row} +
+ $maybe sortableP <- pSortable + $with toSortable <- toSortable sortableP + + $forall OneColonnade{..} <- getColonnade dbtColonnade + ^{widgetFromCell th $ withSortLinks $ toSortable oneColonnadeHead} + $nothing + + $forall row <- rows + + $forall OneColonnade{..} <- getColonnade dbtColonnade + ^{widgetFromCell td $ oneColonnadeEncode row} diff --git a/templates/table/colonnade.julius b/templates/table/colonnade.julius deleted file mode 100644 index 212ecf4ff..000000000 --- a/templates/table/colonnade.julius +++ /dev/null @@ -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; - url.searchParams.set(#{String $ wIdent "table-only"}, 'yes'); - 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, { - 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 - table.querySelector('tbody').innerHTML = data; - }).catch(function(err) { - console.error(err); - }); - } - - }); -})(); diff --git a/templates/table/layout.hamlet b/templates/table/layout.hamlet index eb5651cb3..9e83cfeb6 100644 --- a/templates/table/layout.hamlet +++ b/templates/table/layout.hamlet @@ -1,9 +1,7 @@ -$if not psShortcircuit -
+
+
^{table} - $if pageCount > 1 -

- $# TODO: foreach (reachable pages) print link to that page - _{MsgPage (succ psPage) pageCount} -$else - ^{table} + $if pageCount > 1 +

+ $# TODO: foreach (reachable pages) print link to that page + _{MsgPage (succ psPage) pageCount} diff --git a/templates/table/layout.julius b/templates/table/layout.julius new file mode 100644 index 000000000..45ca89830 --- /dev/null +++ b/templates/table/layout.julius @@ -0,0 +1,79 @@ +(function collonadeClosure() { + 'use strict'; + + document.addEventListener('DOMContentLoaded', function DOMContentLoaded() { + + var ASC = 'asc'; + var DESC = 'desc'; + + function setupSorting(wrapper) { + + var table = wrapper.querySelector('#' + #{String $ wIdent "table-only"}.replace('-table-only', '')); + var ths = Array.from(table.querySelectorAll('th')); + + // attach click handler to each table-header + ths.forEach(function(th) { + th.addEventListener('click', clickHandler); + // TODO: Remove this forEach once column-description is link + Array.from(th.querySelectorAll('a')).forEach(function(a) { + a.style.display = 'none'; + }) + }); + + // handles click on table header + function clickHandler(event) { + event.preventDefault(); + var link = this.querySelector('a'); + if (!link) { + return false; + } + var href = link.getAttribute('href'); + var url = new URL(window.location.origin + window.location.pathname + href); + var order = this.dataset.order || ASC; + url.searchParams.set(#{String $ wIdent "table-only"}, 'yes'); + updateTableFrom(url); + markAsSorted(this, order); + } + + function markAsSorted(th, order) { + ths.forEach(function(th) { + th.classList.remove('sorted-asc', 'sorted-desc'); + }); + th.classList.add('sorted-' + order); + th.dataset.order = order; + } + + function replaceContent(content) { + wrapper.innerHTML = content; + setupSorting(wrapper); + } + + // 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 + replaceContent(data); + table.querySelector('tbody').innerHTML = data; + }).catch(function(err) { + console.error(err); + }); + } + + } + + // TODO: how to get 'terms' only? + var selector = #{String $ wIdent "table-only"}.replace('-only', '-wrapper'); + setupSorting(document.querySelector('#' + selector)); + }); +})(); diff --git a/templates/table/sortable-header.hamlet b/templates/table/sortable-header.hamlet index b5e006b6a..1f358cbff 100644 --- a/templates/table/sortable-header.hamlet +++ b/templates/table/sortable-header.hamlet @@ -1,6 +1,5 @@ ^{cellContents} $maybe flag <- sortableKey -
$case directions $of [SortAsc] "-desc")}>desc @@ -8,7 +7,6 @@ $maybe flag <- sortableKey "-asc")}>asc $of [] "-desc")}>desc - / "-asc")}>asc $of _ $nothing diff --git a/templates/terms.hamlet b/templates/terms.hamlet index d327861ab..4d5e14631 100644 --- a/templates/terms.hamlet +++ b/templates/terms.hamlet @@ -1,5 +1,4 @@

Semesterübersicht -
- ^{table} + ^{table} From e0b3f0921adf4ef57fa1fbac3893a16f72097d62 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Thu, 12 Apr 2018 23:23:35 +0200 Subject: [PATCH 08/20] signal to the user that a column is sortable --- src/Handler/Utils/Table/Pagination.hs | 1 + templates/table/colonnade.lucius | 15 +++++++++++---- templates/table/layout.julius | 12 ++++++++++++ 3 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/Handler/Utils/Table/Pagination.hs b/src/Handler/Utils/Table/Pagination.hs index 776fd3498..9dc99a2ef 100644 --- a/src/Handler/Utils/Table/Pagination.hs +++ b/src/Handler/Utils/Table/Pagination.hs @@ -163,6 +163,7 @@ dbTable PSValidator{..} DBTable{ dbtIdent = (toPathPiece -> dbtIdent), .. } = do sortableAttr = foldMap toAttr directions toAttr SortAsc = Html5.class_ "sorted-asc" toAttr SortDesc = Html5.class_ "sorted-desc" + -- TODO: add class "sortable" if column is sortable $(widgetFile "table/layout") where tblLayout :: Widget -> Handler Html diff --git a/templates/table/colonnade.lucius b/templates/table/colonnade.lucius index 4fcdad6e2..eddc61f79 100644 --- a/templates/table/colonnade.lucius +++ b/templates/table/colonnade.lucius @@ -9,12 +9,11 @@ table th.sorted-desc { color: var(--lightbase); } -table th.sorted-asc::after, -table th.sorted-desc::after { +table th.sortable::after, +table th.sortable::before { content: ''; position: absolute; right: 0; - top: 15px; width: 0; height: 0; transform: translateY(-100%); @@ -22,7 +21,15 @@ table th.sorted-desc::after { 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); } diff --git a/templates/table/layout.julius b/templates/table/layout.julius index 45ca89830..f63f64d8b 100644 --- a/templates/table/layout.julius +++ b/templates/table/layout.julius @@ -24,6 +24,7 @@ function clickHandler(event) { event.preventDefault(); var link = this.querySelector('a'); + // abort if there is no link set for this column if (!link) { return false; } @@ -70,6 +71,17 @@ }); } + + // TODO: Remove after class "sortable" gets set by backend + (function () { + ths.forEach(function(th) { + var link = th.querySelector('a'); + // abort if there is no link set for this column + if (!link) return false; + th.classList.add('sortable'); + }) + })(); + } // TODO: how to get 'terms' only? From 4f6d0ffbf71653b74d68e7ade494955617d0d684 Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Thu, 12 Apr 2018 23:29:13 +0200 Subject: [PATCH 09/20] slightly brighter dark --- templates/default-layout.lucius | 3 ++- templates/standalone/modal.lucius | 2 +- templates/widgets/navbar.lucius | 11 +++++------ 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/templates/default-layout.lucius b/templates/default-layout.lucius index cc33bfe58..3574d3a43 100644 --- a/templates/default-layout.lucius +++ b/templates/default-layout.lucius @@ -20,7 +20,8 @@ --fontbase: #34303a; --fontsec: #5b5861; /* THEME 4 */ - --darkbase: #263C4C; + --darkerbase: #274a65; + --darkbase: #425d79; --lightbase: #598EB5; --lighterbase: #5F98C2; --whitebase: #FCFFFA; diff --git a/templates/standalone/modal.lucius b/templates/standalone/modal.lucius index a511f58c6..f9e1db4e2 100644 --- a/templates/standalone/modal.lucius +++ b/templates/standalone/modal.lucius @@ -70,7 +70,7 @@ justify-content: center; width: 30px; height: 30px; - background-color: var(--darkbase); + background-color: var(--darkerbase); border-radius: 2px; cursor: pointer; z-index: 20; diff --git a/templates/widgets/navbar.lucius b/templates/widgets/navbar.lucius index b04c47366..b1fe881c4 100644 --- a/templates/widgets/navbar.lucius +++ b/templates/widgets/navbar.lucius @@ -8,10 +8,10 @@ height: var(--header-height); padding-right: 5vw; padding-left: 340px; - background: var(--darkbase); /* Old browsers */ - background: -moz-linear-gradient(bottom, var(--darkbase) 0%, #425d79 100%); /* FF3.6-15 */ - background: -webkit-linear-gradient(bottom, var(--darkbase) 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: var(--darkerbase); /* Old browsers */ + background: -moz-linear-gradient(bottom, var(--darkerbase) 0%, #425d79 100%); /* FF3.6-15 */ + background: -webkit-linear-gradient(bottom, var(--darkerbase) 0%,#425d79 100%); /* Chrome10-25,Safari5.1-6 */ + background: linear-gradient(to top, var(--darkerbase) 0%,#425d79 100%); /* W3C, IE10+, FF16+, Chrome26+, Opera12+, Safari7+ */ color: white; box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1); z-index: 10; @@ -86,8 +86,7 @@ } .navbar .navbar__list-item:not(.navbar__list-item--active):hover { - background-color: var(--darkbase); - color: var(--whitebase); + background-color: var(--darkerbase); } .navbar .navbar__list-item:not(.navbar__list-item--active):hover .navbar__link-wrapper { color: var(--whitebase); From 174297c2ba2119aa0cceebab585c86d81fcb50ed Mon Sep 17 00:00:00 2001 From: Felix Hamann Date: Thu, 12 Apr 2018 23:31:01 +0200 Subject: [PATCH 10/20] asidenav with distinguishable title and active-state --- templates/widgets/asidenav.hamlet | 9 +++++---- templates/widgets/asidenav.lucius | 19 ++++++++++++++++--- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/templates/widgets/asidenav.hamlet b/templates/widgets/asidenav.hamlet index a46c06ad9..b19ab9d4f 100644 --- a/templates/widgets/asidenav.hamlet +++ b/templates/widgets/asidenav.hamlet @@ -18,10 +18,11 @@ $newline never WiSe 17/18