From 48ea0fdedeaa4b75e113a521d63682fed3881c4e Mon Sep 17 00:00:00 2001
From: Ron Lucke <lucke@elan-ev.de>
Date: Fri, 27 Sep 2024 11:24:20 +0000
Subject: [PATCH] =?UTF-8?q?Neues=20Layout=20f=C3=BCr=20den=20Header?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Closes #4478

Merge request studip/studip!3393
---
 lib/models/Course.php                         |   1 +
 .../assets/stylesheets/mixins/colors.scss     |  71 ++++
 resources/assets/stylesheets/scss/header.scss | 343 +++++++++++-------
 resources/assets/stylesheets/scss/index.scss  |   5 -
 .../assets/stylesheets/scss/layouts.scss      | 180 +--------
 .../assets/stylesheets/scss/navigation.scss   |   3 +-
 resources/assets/stylesheets/scss/tabs.scss   |   6 +-
 templates/header.php                          |  25 +-
 8 files changed, 313 insertions(+), 321 deletions(-)

diff --git a/lib/models/Course.php b/lib/models/Course.php
index c8475c27e10..1ff49f4bb49 100644
--- a/lib/models/Course.php
+++ b/lib/models/Course.php
@@ -1770,6 +1770,7 @@ class Course extends SimpleORMap implements Range, PrivacyObject, StudipItem, Fe
             'number-name-semester' => '%3$s %1$s (%4$s)',
             'number-type-name'     => '%3$s %2$s: %1$s',
             'sem-duration-name'    => '%4$s',
+            'type'                 => '%2$s',
             'type-name'            => '%2$s: %1$s',
             'type-number-name'     => '%2$s: %3$s %1$s',
         ];
diff --git a/resources/assets/stylesheets/mixins/colors.scss b/resources/assets/stylesheets/mixins/colors.scss
index 560733f0ebe..041bc626cb7 100644
--- a/resources/assets/stylesheets/mixins/colors.scss
+++ b/resources/assets/stylesheets/mixins/colors.scss
@@ -212,3 +212,74 @@ $calendar-category-18-aux:  $brown-20;
 
 $calendar-category-255:     $light-gray-color-60;
 $calendar-category-255-aux: $light-gray-color-20;
+
+
+/* * * * * * * * * * *
+ 6.x  C O L O R S
+ * * * * * * * * * * */
+
+$color--blue-1: #28497c;
+$color--gray-1: #101010;
+$color--gray-2: #3c454e;
+$color--gray-3: #676767;
+$color--gray-4: #909090;
+$color--gray-5: #d8d8d8;
+$color--gray-6: #ededed;
+$color--gray-7: #fbfbfc;
+$color--green-1: #6ead10;
+$color--red-1: #d60000;
+$color--white: #fff;
+$color--yellow-1: #ffbc33;
+
+$color--global-background: $color--white;
+
+$color--brand-primary: $color--blue-1;
+$color--brand-secondary: $color--gray-2;
+
+$color--font-primary: $color--gray-1;
+$color--font-secondary: $color--gray-3;
+$color--font-inactive: $color--gray-4;
+$color--font-inverted: $color--white;
+
+$color--main-navigation-background: $color--gray-7;
+$color--main-navigation-border: $color--gray-5;
+
+$color--sidebar-marker-focus: $color--gray-5;
+$color--sidebar-marker-hover: $color--gray-5;
+$color--sidebar-focus: $color--gray-6;
+$color--sidebar-hover: $color--gray-6;
+
+$color--dialog-overlay: $color--gray-1;
+
+$color--tile-border-focus: $color--gray-4;
+$color--tile-border-hover: $color--gray-4;
+$color--tile-border: $color--gray-5;
+$color--tile-background: $color--gray-7;
+$color--tile-background-focus: $color--gray-6;
+$color--tile-background-hover: $color--gray-6;
+
+$color--content-box-border: $color--gray-5;
+$color--content-box-background: $color--white;
+
+$color--table-header: $color--gray-6;
+$color--table-border: $color--gray-6;
+$color--table-focus: $color--gray-6;
+$color--table-hover: $color--gray-6;
+
+$color--button-background:$color--white;
+$color--button-border: $color--blue-1;
+$color--button-focus: $color--blue-1;
+$color--button-hover: $color--blue-1;
+
+$color--input-field-border: $color--gray-5;
+$color--input-field-background: $color--white;
+
+$color--divider: $color--gray-6;
+$color--line: $color--gray-6;
+
+$color--shadow: $color--gray-4;
+$color--focus: $color--gray-4;
+
+$color--warning: $color--red-1;
+$color--attention: $color--yellow-1;
+$color--good: $color--green-1;
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/header.scss b/resources/assets/stylesheets/scss/header.scss
index 5c95b4d4126..006716f9f2d 100644
--- a/resources/assets/stylesheets/scss/header.scss
+++ b/resources/assets/stylesheets/scss/header.scss
@@ -1,9 +1,10 @@
-/* --- header.css ----------------------------------------------------------- */
 #main-header {
+    grid-column: 1 / 3;
+    grid-row: 1 / 2;
     box-sizing: border-box;
     padding-top: $bar-bottom-container-height;
+    margin-bottom: 10px;
 }
-
 #top-bar {
     background-color: var(--base-color);
     border: 1px var(--brand-color-darker);
@@ -11,8 +12,10 @@
     border-bottom-style: solid;
     height: $bar-bottom-container-height;
     width: 100%;
+    min-width: $site-width;
 
     display: flex;
+    flex: 0 1 auto;
     flex-direction: row;
     flex-wrap: nowrap;
     justify-content: flex-start;
@@ -23,160 +26,254 @@
     top: 0;
     z-index: 1001;
 
-}
-
-#responsive-menu,
-#site-title {
-    flex: 0 0 auto;
-    z-index: 2;
-}
+    #site-title {
+        flex: 1;
+        color: var(--white);
+        margin-left: 0;
+        z-index: 1002;
+        line-height: $bar-bottom-container-height;
+        white-space: nowrap;
+    }
 
-#site-title {
-    padding: 0 5px;
-}
+    #header-links {
+        flex: 0 1 auto;
+        justify-self: flex-end;
 
-// Fix header covering relevant other areas
-// $see https://gitlab.studip.de/studip/studip/-/issues/1019
-html {
-    scroll-padding-top: calc($bar-bottom-container-height + 1em);
-}
+        > ul {
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            list-style-type: none;
+            height: 40px;
+            padding: 0;
 
-#header-links {
-    > ul > li > a {
-        color: var(--white);
-        margin: 0 6px;
-        text-decoration: none;
-        &:hover {
-            text-decoration: underline;
-        }
-    }
-}
+            > li {
+                margin: 2px;
+                padding: 0 10px;
 
-#header-links {
-    flex: 0 1 auto;
-    justify-self: flex-end;
-    > ul {
-        display: flex;
-        align-items: center;
-        justify-content: space-between;
-        list-style-type: none;
-        height: 40px;
-        padding: 0;
-        > li {
-            margin: 2px;
-            padding: 0 10px;
+                > a {
+                    color: var(--white);
+                    margin: 0 6px;
+                    text-decoration: none;
+                    &:hover {
+                        text-decoration: underline;
+                    }
+                }
+            }
         }
     }
 }
 
-#avatar-menu-container {
-    display: inline-flex;
-}
+#navigation-level-1 {
+    display: flex;
+    flex-direction: row;
+    flex-wrap: nowrap;
+    justify-content: space-between;
+    align-content: stretch;
+    align-items: stretch;
+    background-color: $color--main-navigation-background;
+    border-bottom: 1px solid $color--main-navigation-border;
+    box-sizing: border-box;
+    display: flex;
+    justify-content: flex-start;
+    min-width: $site-width;
+    width: 100%;
+    height: $header-height;
+    z-index: 3;
 
-#avatar-menu {
-    height: 30px;
-    margin: 0;
-    vertical-align: text-bottom;
-    z-index: 1003;
-
-    .action-menu-icon {
-        border: 1px solid var(--dark-gray-color-40);
-        background-color: var(--dark-gray-color-5);
-        height: 28px;
-        margin: 0 32px 0 0;
-        position: relative;
-        width: 28px;
-        z-index: 1;
-
-        img {
-            height: 100%;
-            width: 100%;
-        }
+    // #navigation-level-1-items -> navigation.scss
 
-        // Add arrow on the right
-        @include icon(after, arr_1down, info_alt);
+    #top-logo {
+        flex: 0 1 auto;
+        margin: -13px 12px 0 20px;
 
-        &::after {
-            background-position: center;
+        &.studip-logo {
+            @include hide-text();
+            @include retina-background-image('logos/studip4-logo.png', 'logos/studip4-logo@2x.png', 130px, 92px);
             background-repeat: no-repeat;
-            padding: 7px 8px;
-            position: absolute;
-            left: 100%;
-            top: 0;
-        }
-
-        #notification-container + & {
-            border-left: 0;
+            background-image: none, url("#{$image-path}/logos/studip4-logo.svg");
+            background-size: 130px 92px;
+            background-position: left;
+            display: block;
+            width: 130px;
+            height: 81px;
+            margin-right: 30px;
         }
     }
 }
-.action-menu.avatar-menu {
-    z-index: 1002;
 
-    .action-menu-title{
-        margin: 0 0 0.3em;
+#current-page-structure {
+    display: flex;
+    position: relative;
+    width: 100%;
+    min-width: $site-width;
+    flex-direction: column;
+    flex-wrap: nowrap;
+    align-content: stretch;
+    align-items: stretch;
+    justify-content: flex-start;
+    flex-grow: 1;
+    
+    &.oversized {
+        overflow: visible;
     }
 
-    .action-menu-content {
-        position: absolute;
-        top: 41px;
-        right: 0;
-
-        /*padding: 4px 28px 4px 8px;*/
-        background: var(--white);
-        box-shadow: 1px 1px 1px var(--dark-gray-color-60);
-        text-align: left;
-        white-space: nowrap;
+    .colorblock {
+        display: inline-block;
+        vertical-align: middle;
+        width: 8px;
+        height: 48px;
+    }
 
-        a:link,
-        a:visited {
-            color: var(--base-color);
+    .contextless & {
+        .colorblock {
+            width: 0;
         }
-        a:hover,
-        a:active {
-            color: var(--active-color);
+    }
+
+    #context-title {
+        font-size: 24px;
+        color: $color--font-primary;
+        height: 30px;
+        padding: 10px 15px 5px 15px;
+        max-height: 30px;
+        overflow: hidden;
+        background-color: $color--main-navigation-background;
+    
+        > .context-avatar {
+            margin: 0 5px 0 -6px;
+            vertical-align: top;
+            max-width: 36px;
+            max-height: 36px;
         }
 
-        div {
-            color: var(--black);
+        > .course-type {
+            font-style: normal;
         }
+        > .course-name {
+            font-weight: 700;
+        }
+        > .course-semester {
+            font-style: oblique;
+        }
+    }
+
+    .tabs_wrapper {
+        display: flex;
+        flex-direction: row;
+        align-items: stretch;
+        justify-content: space-between;
+        background-color: $color--main-navigation-background;
+        font-size: 0.9em;
+        color: $color--font-primary;
+        min-height: 2.3em;
+        border-bottom: 1px solid $color--main-navigation-border;
+        padding-left: $page-margin;
+        padding-top: 10px;
+    }
+
+    #tabs { 
+        transition: margin-left;
+        transition-duration: var(--transition-duration);
+        transition-delay: 500ms;
+        font-size: 1.25em;
+    }
+
+    > ul {
+        flex: 1 1 auto;
     }
 }
 
-.header_avatar_container {
-    align-items: end;
-    flex: 0;
+#responsive-menu,
+#site-title {
+    flex: 0 0 auto;
+    z-index: 2;
 }
 
 #site-title {
-    flex: 1;
-    color: var(--white);
-    margin-left: 0;
-    z-index: 1002;
-    line-height: $bar-bottom-container-height;
-    white-space: nowrap;
+    padding: 0 5px;
 }
 
-.studip-logo {
-    @include hide-text();
-    background-repeat: no-repeat;
+#avatar-menu-container {
+    display: inline-flex;
 
-    @include retina-background-image('logos/studip4-logo.png', 'logos/studip4-logo@2x.png', 130px, 92px);
-    background-image: none, url("#{$image-path}/logos/studip4-logo.svg");
+    &.header_avatar_container {
+        align-items: end;
+        flex: 0;
+    }
 
-    background-size: 130px 92px;
-    display: block;
-    width: 130px;
-    height: 81px;
-}
+    #avatar-menu {
+        height: 30px;
+        margin: 0;
+        vertical-align: text-bottom;
+        z-index: 1003;
 
-#top-logo {
-    margin-left: 20px;
-    margin-right: 12px;
-}
+        .action-menu.avatar-menu {
+            z-index: 1002;
 
-#navigation-level-1 {
-    background-color: var(--dark-gray-color-5);
-    height: $header-height;
-    z-index: 3;
+            .action-menu-icon {
+                border: 1px solid var(--dark-gray-color-40);
+                background-color: var(--dark-gray-color-5);
+                height: 28px;
+                margin: 0 32px 0 0;
+                position: relative;
+                width: 28px;
+                z-index: 1;
+        
+                img {
+                    height: 100%;
+                    width: 100%;
+                }
+        
+                // Add arrow on the right
+                @include icon(after, arr_1down, info_alt);
+        
+                &::after {
+                    background-position: center;
+                    background-repeat: no-repeat;
+                    padding: 7px 8px;
+                    position: absolute;
+                    left: 100%;
+                    top: 0;
+                }
+        
+                #notification-container + & {
+                    border-left: 0;
+                }
+            }
+        
+            .action-menu-title {
+                margin: 0 0 0.3em;
+            }
+        
+            .action-menu-content {
+                position: absolute;
+                top: 41px;
+                right: 0;
+                background: var(--white);
+                box-shadow: 1px 1px 1px var(--dark-gray-color-60);
+                text-align: left;
+                white-space: nowrap;
+        
+                a:link,
+                a:visited {
+                    color: var(--base-color);
+                }
+                a:hover,
+                a:active {
+                    color: var(--active-color);
+                }
+        
+                div {
+                    color: var(--black);
+                }
+            }
+        }
+    }
 }
+
+// Fix header covering relevant other areas
+// $see https://gitlab.studip.de/studip/studip/-/issues/1019
+html {
+    scroll-padding-top: calc($bar-bottom-container-height + 1em);
+}
\ No newline at end of file
diff --git a/resources/assets/stylesheets/scss/index.scss b/resources/assets/stylesheets/scss/index.scss
index 77112f6d5bd..046d027940f 100644
--- a/resources/assets/stylesheets/scss/index.scss
+++ b/resources/assets/stylesheets/scss/index.scss
@@ -5,11 +5,6 @@ body {
 $login-page-margin: 50px;
 $gap-between-boxes: calc($login-page-margin / 2);
 
-#main-header {
-    grid-column: 1 / 3;
-    grid-row: 1 / 1;
-}
-
 #content {
     grid-column: 1 / 3;
     grid-row: 2 / 2;
diff --git a/resources/assets/stylesheets/scss/layouts.scss b/resources/assets/stylesheets/scss/layouts.scss
index 6d0454af0cf..b76791ff20b 100644
--- a/resources/assets/stylesheets/scss/layouts.scss
+++ b/resources/assets/stylesheets/scss/layouts.scss
@@ -6,8 +6,9 @@ html {
 }
 
 body {
-    background-color: var(--white);
     display: grid;
+    background-color: var(--white);
+    width: 100%;    
     grid-column-gap: 5px;
     grid-row-gap: $grid-gap;
     grid-template-columns: ($sidebar-width + $sidebar-padding) minmax(auto, calc(100vw - $sidebar-width - $sidebar-padding));
@@ -18,104 +19,7 @@ body {
     }
 }
 
-#main-header {
-    grid-column: 1 / 3;
-    grid-row: 1 / 2;
-}
-
-#top-bar {
-    height: 40px;
-    min-width: $site-width;
-    z-index: 1001; // High enough so it will be above the sidebar
-}
-
-#navigation-level-1 {
-    align-content: stretch;
-    align-items: stretch;
-    background-color: var(--white);
-    border-radius: 0 0 2px 2px;
-    box-sizing: border-box;
-    display: flex;
-    justify-content: flex-start;
-    min-width: $site-width;
-    width: 100%;
-
-    #top-logo {
-        flex: 0 1 auto;
-        margin-right: 12px;
-        margin-top: -13px;
-    }
-}
-
-#navigation-level-1-items {
-    flex: 1;
-    height: 55px;
-}
-
 /* --- Layouts -------------------------------------------------------------- */
-#current-page-structure {
-    background-color: var(--white);
-    border-radius: 0 0 2px 2px;
-    position: relative;
-    width: 100%;
-
-    &.oversized {
-        overflow: visible;
-    }
-
-    .colorblock {
-        position: absolute;
-        top: 0;
-        left: 0;
-        bottom: 0;
-        width: $page-margin;
-    }
-
-    .contextless & {
-        .colorblock {
-            width: 0;
-        }
-    }
-}
-
-#navigation-level-2 {
-    #context-title {
-        font-size: 1.1em;
-        height: 30px;
-        padding-left: $page-margin;
-        max-height: 30px;
-        overflow: hidden;
-
-        background: linear-gradient(to bottom, var(--dark-gray-color-5), var(--dark-gray-color-10));
-
-        > .context_icon {
-            margin: 7px 1px 0 9px;
-            vertical-align: text-bottom;
-        }
-    }
-
-    .tabs_wrapper {
-        align-items: stretch;
-        background-color: var(--dark-gray-color-10);
-        border-bottom: 1px solid var(--dark-gray-color-40);
-        display: flex;
-        flex-direction: row;
-        flex-wrap: nowrap;
-        font-size: 0.9em;
-        justify-content: space-between;
-        padding-left: 27px;
-    }
-
-    .contextless & {
-        #context-title {
-            display: none;
-        }
-
-        .tabs_wrapper {
-            padding-left: 0;
-        }
-    }
-}
 
 #tabs {
     width: 100%;
@@ -184,21 +88,6 @@ body {
     min-height: 45px;
 }
 
-#context-title {
-    font-size: 1.1em;
-    height: 30px;
-    padding-left: $page-margin;
-    max-height: 30px;
-    overflow: hidden;
-
-    background: linear-gradient(to bottom, var(--dark-gray-color-5), var(--dark-gray-color-10));
-
-    > .context_icon {
-        margin: 7px 1px 0 9px;
-        vertical-align: text-bottom;
-    }
-}
-
 #page-title {
     font-weight: bold;
     font-size: 1.4em;
@@ -245,68 +134,3 @@ body {
         }
     }
 }
-
-#navigation-level-1 {
-    display: flex;
-    flex-direction: row;
-    flex-wrap: nowrap;
-    align-content: stretch;
-    align-items: stretch;
-    justify-content: space-between;
-
-    width: 100%;
-    min-width: $site-width;
-
-    border-bottom: 1px solid var(--light-gray-color-40);
-}
-
-#top-bar {       // second row of flex-main
-    flex: 0 1 auto;
-    z-index: 1001; // High enough so it will be above the sidebar
-}
-
-body {
-    width: 100%;
-
-    #current-page-structure { // third row of flex-main
-        display: flex;
-        flex-direction: column;
-        flex-wrap: nowrap;
-        align-content: stretch;
-        align-items: stretch;
-        justify-content: flex-start;
-
-        flex-grow: 1;
-
-        min-width: $site-width;
-
-        .tabs_wrapper {
-            display: flex;
-            flex-direction: row;
-            align-items: stretch;
-            justify-content: space-between;
-            background-color: var(--dark-gray-color-10);
-            font-size: 0.9em;
-            min-height: 2.3em;
-            border-bottom: 1px solid var(--dark-gray-color-40);
-        }
-
-        #tabs { // row 1 of layout_page
-            padding-left: $page-margin;
-            transition: margin-left;
-            transition-duration: var(--transition-duration);
-            transition-delay: 500ms;
-        }
-
-        > ul { // column 1 of flex-header
-            flex: 1 1 auto;
-        }
-
-        #top-logo {
-            flex: 0 1 auto;
-            margin-right: 12px;
-            margin-top: -13px;
-
-        }
-    }
-}
diff --git a/resources/assets/stylesheets/scss/navigation.scss b/resources/assets/stylesheets/scss/navigation.scss
index d51c76d598c..4af54bfd679 100644
--- a/resources/assets/stylesheets/scss/navigation.scss
+++ b/resources/assets/stylesheets/scss/navigation.scss
@@ -1,7 +1,8 @@
 /* --- main navigation ----------------------------------------------------- */
 body:not(.fixed) #navigation-level-1-items {
+    flex: 1;
+    height: 55px;
     align-self: flex-end;
-
     margin: 0 0 4px 5px;
     padding: 20px 0 0 0;
     z-index: 1000;
diff --git a/resources/assets/stylesheets/scss/tabs.scss b/resources/assets/stylesheets/scss/tabs.scss
index 63bf1a0372a..b5c90aae6c1 100644
--- a/resources/assets/stylesheets/scss/tabs.scss
+++ b/resources/assets/stylesheets/scss/tabs.scss
@@ -31,8 +31,13 @@ div.clear
     .quiet img { opacity: 0.25; }
 
     li {
+        margin: 0 8px;
+        &:first-child {
+            margin-left: 0;
+        }
         &:last-child {
             border-right: none;
+            margin-right: 0;
         }
         &.current {
             color: var(--base-color);
@@ -57,7 +62,6 @@ div.clear
 
         padding: 5px 8px;
         white-space: nowrap;
-        height: 23px;
     }
 }
 
diff --git a/templates/header.php b/templates/header.php
index 1be47abd629..e5c8943c24d 100644
--- a/templates/header.php
+++ b/templates/header.php
@@ -275,25 +275,24 @@ if ($navigation) {
         <? endif ?>
 
         <? if (Context::get() || PageLayout::isHeaderEnabled()): ?>
-            <? if (is_object($GLOBALS['perm']) && !$GLOBALS['perm']->have_perm('admin') && $contextable) : ?>
-                <? $membership = CourseMember::find([Context::get()->id, $GLOBALS['user']->id]) ?>
-                <? if ($membership) : ?>
-                    <a href="<?= URLHelper::getLink('dispatch.php/my_courses/groups') ?>"
-                       data-dialog aria-label="<?= _('Gruppenzuordnung der Veranstaltung ändern') ?>"
-                       title="<?= _('Gruppenzuordnung der Veranstaltung ändern') ?>"
-                       class="colorblock gruppe<?= $membership ? $membership['gruppe'] : 1 ?>"></a>
-                <? endif ?>
-            <? endif ?>
             <? if ($contextable) : ?>
                 <div id="context-title">
+                <? if (is_object($GLOBALS['perm']) && !$GLOBALS['perm']->have_perm('admin')) : ?>
+                        <? $membership = CourseMember::find([Context::get()->id, $GLOBALS['user']->id]) ?>
+                        <? if ($membership) : ?>
+                            <a href="<?= URLHelper::getLink('dispatch.php/my_courses/groups') ?>"
+                            data-dialog
+                            class="colorblock gruppe<?= $membership ? $membership['gruppe'] : 1 ?>"></a>
+                        <? endif ?>
+                    <? endif ?>
                     <? if (Context::isCourse()) : ?>
-                        <?= Icon::create('seminar', Icon::ROLE_INFO)->asImg(20, ['class' => 'context_icon']) ?>
-                        <?= htmlReady(Context::get()->getFullName()) ?>
+                        <?= CourseAvatar::getAvatar(Context::get()->id)->getImageTag(Avatar::NORMAL, ['class' => 'context-avatar']) ?>
+                        <span class="course-type"><?= htmlReady(Context::get()->getFullName('type')) ?>:</span> <span class="course-name"><?= htmlReady(Context::get()->getFullName('name')) ?></span>
                         <? if ($GLOBALS['user']->config->SHOWSEM_ENABLE && !Context::get()->isOpenEnded()): ?>
-                            (<?= htmlReady(Context::get()->getTextualSemester()) ?>)
+                            <span class="course-semester">(<?= htmlReady(Context::get()->getTextualSemester()) ?>)</span>
                         <? endif ?>
                     <? elseif (Context::isInstitute()) : ?>
-                        <?= Icon::create('institute', Icon::ROLE_INFO)->asImg(20, ['class' => 'context_icon']) ?>
+                        <?= InstituteAvatar::getAvatar(Context::get()->id)->getImageTag(Avatar::SMALL, ['class' => 'context-avatar']) ?>
                         <?= htmlReady(Context::get()->name) ?>
                     <? endif ?>
                 </div>
-- 
GitLab