From bcfc77c260ddc12e2f1b0aec005060943a6bb246 Mon Sep 17 00:00:00 2001 From: tgloeggl <tgloeggl@uos.de> Date: Fri, 4 Aug 2023 14:08:20 +0200 Subject: [PATCH 1/3] working on action menu --- assets/css/opencast.scss | 59 +++++++++++++++ vueapp/components/Studip/StudipActionMenu.vue | 73 ++++++++++--------- 2 files changed, 99 insertions(+), 33 deletions(-) diff --git a/assets/css/opencast.scss b/assets/css/opencast.scss index ed81908fa..81119aee0 100644 --- a/assets/css/opencast.scss +++ b/assets/css/opencast.scss @@ -6,6 +6,7 @@ $item-width : 20em; $item-height-small: auto; $item-width-small : 16em; $episode-background: $light-gray-color-20; +$action-menu-icon-size: 20px; /* * * * * * * * * * * * * * * * * */ /* G L O B A L E K L A S S E N */ @@ -473,6 +474,64 @@ h2.oc--loadingbar, .oc--loadingbar-title { display: flex; justify-content: center; align-items: center; + + .action-menu-icon { + background: transparent; + border: 0; + + // Create animated icon that changes to close icon on activation/hover + span { + width: 5px; + height: 5px; + transform: translate(-2.5px); + transition: all .25s ease-in-out; + + display: block; + position: absolute; + background: $base-color; + border-radius: 50%; + opacity: 1; + left: 50%; + + &:nth-child(1) { + top: 0px; + } + + &:nth-child(2) { + top: 10px; + transform: translate(-2.5px, -2.5px); + } + + &:nth-child(3) { + bottom: 0; + } + } + } + + .is-open { + z-index: 3; + .action-menu-icon { + span { + border-radius: 0; + + &:nth-child(1) { + left: 0; + transform: rotate(45deg) translate(calc(($action-menu-icon-size / 4) + 0.5px), calc(($action-menu-icon-size / 4) + 0.5px)); + width: 100%; + } + + &:nth-child(2) { + opacity: 0; + } + + &:nth-child(3) { + left: 0; + transform: rotate(-45deg) translate(calc($action-menu-icon-size / 4), calc(-1 * ($action-menu-icon-size / 4))); + width: 100%; + } + } + } + } } /* * * * * * * * * * * * * * * * * * * * * * * * * * */ diff --git a/vueapp/components/Studip/StudipActionMenu.vue b/vueapp/components/Studip/StudipActionMenu.vue index f3b6bb390..9111fb090 100644 --- a/vueapp/components/Studip/StudipActionMenu.vue +++ b/vueapp/components/Studip/StudipActionMenu.vue @@ -1,18 +1,13 @@ <template> <nav v-if="shouldCollapse" class="action-menu"> - <button v-if="render_button_icon" class="action-menu-icon" :title="$gettext('Aktionen')" aria-expanded="false"> + <button class="action-menu-icon" :title="title" aria-expanded="false"> <span></span> <span></span> <span></span> </button> - <a v-else class="action-menu-icon" :title="$gettext('Aktionen')" aria-expanded="false" :aria-label="$gettext('Aktionsmenü')" href="#"> - <div></div> - <div></div> - <div></div> - </a> <div class="action-menu-content"> <div class="action-menu-title"> - {{ 'Aktionen' }} + {{ $gettext('Aktionen') }} </div> <ul class="action-menu-list"> <li v-for="item in navigationItems" :key="item.id" class="action-menu-item"> @@ -22,30 +17,45 @@ {{ item.label }} </a> + <label v-else-if="item.icon" class="undecorated" v-bind="linkAttributes(item)" v-on="linkEvents(item)"> + <studip-icon :shape="item.icon.shape" :role="item.icon.role" :name="item.name" :title="item.label" v-bind="item.attributes ?? {}"></studip-icon> + {{ item.label }} + </label> + <template v-else> + <span class="action-menu-no-icon"></span> + <button :name="item.name" v-bind="Object.assign(item.attributes ?? {}, linkAttributes(item))" v-on="linkEvents(item)"> + {{ item.label }} + </button> + </template> </li> </ul> </div> </nav> - <nav v-else class="action-menu"> - <ul class="action-menu-list"> - <li v-for="item in navigationItems" :key="item.id" class="action-menu-item"> - <a v-bind="linkAttributes(item)" v-on="linkEvents(item)"> - <studip-icon :title="item.label" :shape="item.icon.shape" :role="item.icon.role" :size="20"></studip-icon> - </a> - </li> - </ul> + <nav v-else> + <a v-for="item in navigationItems" :key="item.id" v-bind="linkAttributes(item)" v-on="linkEvents(item)"> + <studip-icon :title="item.label" :shape="item.icon.shape" :role="item.icon.role" :size="20"></studip-icon> + </a> </nav> </template> <script> -import StudipIcon from '@studip/StudipIcon.vue'; +import StudipIcon from '@studip/StudipIcon.vue' + export default { - components: { StudipIcon }, name: 'studip-action-menu', + + components: { + StudipIcon + }, + props: { items: Array, collapseAt: { - default: true, + default: null, + }, + context: { + type: String, + default: '' } }, data () { @@ -71,7 +81,8 @@ export default { linkEvents (item) { let events = {}; if (item.emit) { - events.click = () => { + events.click = (e) => { + e.preventDefault(); this.$emit.apply(this, [item.emit].concat(item.emitArguments)); this.close(); }; @@ -85,13 +96,13 @@ export default { computed: { navigationItems () { return this.items.map((item) => { - let classes = item.classes || ''; + let classes = item.classes ?? ''; if (item.disabled) { classes += " action-menu-item-disabled"; } return { label: item.label, - url: item.url || false, + url: item.url || '#', emit: item.emit || false, emitArguments: item.emitArguments || [], icon: item.icon ? { @@ -99,6 +110,7 @@ export default { role: item.disabled ? 'inactive' : 'clickable' } : false, type: item.type || 'link', + name: item.name ?? null, classes: classes.trim(), attributes: item.attributes || {}, disabled: item.disabled, @@ -106,24 +118,19 @@ export default { }); }, shouldCollapse () { - if (this.collapseAt === false) { + const collapseAt = this.collapseAt ?? this.getStudipConfig('ACTIONMENU_THRESHOLD'); + + if (collapseAt === false) { return false; } - if (this.collapseAt === true) { + if (collapseAt === true) { return true; } - return Number.parseInt(this.collapseAt) <= this.items.length; + return Number.parseInt(collapseAt) <= this.items.length; }, - - render_button_icon() { - return (window.OpencastPlugin?.STUDIP_VERSION && window.OpencastPlugin.STUDIP_VERSION >= 5.2) ? true : false; + title () { + return this.context ? this.$gettextInterpolate(this.$gettext('Aktionsmenü für %{context}'), {context: this.context}) : this.$gettext('Aktionsmenü'); } } } </script> - -<style lang="scss"> -.action-menu-list .action-menu-item a { - cursor: pointer; -} -</style> From 5a475614e60e23d7f3e5a90597188187900a771d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Till=20Gl=C3=B6ggler?= <till@gundk.it> Date: Fri, 4 Aug 2023 14:42:53 +0200 Subject: [PATCH 2/3] fix typo --- migrations/053_add_default_config_option.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/migrations/053_add_default_config_option.php b/migrations/053_add_default_config_option.php index 948ca19f4..7a68f6fce 100644 --- a/migrations/053_add_default_config_option.php +++ b/migrations/053_add_default_config_option.php @@ -18,7 +18,7 @@ public function up() $stmt->execute([ 'name' => 'OPENCAST_DEFAULT_SERVER', 'section' => 'opencast', - 'description' => 'Das ist der standaramäßig verwendete Opencast-Server.', + 'description' => 'Das ist der standardmäßig verwendete Opencast-Server.', 'range' => 'global', 'type' => 'integer', 'value' => $config_id From 91fbeda5868aae59c83c2be5f58f48f13a37a8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Till=20Gl=C3=B6ggler?= <till@gundk.it> Date: Sat, 5 Aug 2023 09:24:39 +0200 Subject: [PATCH 3/3] fix action menu for 4.6-5.3 --- assets/css/opencast.scss | 91 +++++++++++++++++++++------------------- 1 file changed, 48 insertions(+), 43 deletions(-) diff --git a/assets/css/opencast.scss b/assets/css/opencast.scss index 81119aee0..10ab9c31d 100644 --- a/assets/css/opencast.scss +++ b/assets/css/opencast.scss @@ -466,6 +466,10 @@ h2.oc--loadingbar, .oc--loadingbar-title { } } +/* * * * * * * * * * * * * * */ +/* A C T I O N M E N U */ +/* * * * * * * * * * * * * * */ + .oc--actions-container { min-width: 2em; border-left: 1px solid $light-gray-color-40; @@ -474,66 +478,67 @@ h2.oc--loadingbar, .oc--loadingbar-title { display: flex; justify-content: center; align-items: center; +} - .action-menu-icon { - background: transparent; - border: 0; +.action-menu-icon { + background: transparent; + border: 0; - // Create animated icon that changes to close icon on activation/hover - span { - width: 5px; - height: 5px; - transform: translate(-2.5px); - transition: all .25s ease-in-out; + // Create animated icon that changes to close icon on activation/hover + span { + width: 5px; + height: 5px; + transform: translate(-2.5px); + transition: all .25s ease-in-out; - display: block; - position: absolute; - background: $base-color; - border-radius: 50%; - opacity: 1; - left: 50%; + display: block; + position: absolute; + background: $base-color; + border-radius: 50%; + opacity: 1; + left: 50%; - &:nth-child(1) { - top: 0px; - } + &:nth-child(1) { + top: 0px; + } - &:nth-child(2) { - top: 10px; - transform: translate(-2.5px, -2.5px); - } + &:nth-child(2) { + top: 10px; + transform: translate(-2.5px, -2.5px); + } - &:nth-child(3) { - bottom: 0; - } + &:nth-child(3) { + bottom: 0; } } +} - .is-open { - z-index: 3; - .action-menu-icon { - span { - border-radius: 0; +.action-menu-wrapper.is-open { + z-index: 3; + .action-menu-icon { + span { + border-radius: 0; - &:nth-child(1) { - left: 0; - transform: rotate(45deg) translate(calc(($action-menu-icon-size / 4) + 0.5px), calc(($action-menu-icon-size / 4) + 0.5px)); - width: 100%; - } + &:nth-child(1) { + left: 0; + transform: rotate(45deg) translate(5.5px, 5.5px); + width: 100%; + } - &:nth-child(2) { - opacity: 0; - } + &:nth-child(2) { + opacity: 0; + } - &:nth-child(3) { - left: 0; - transform: rotate(-45deg) translate(calc($action-menu-icon-size / 4), calc(-1 * ($action-menu-icon-size / 4))); - width: 100%; - } + &:nth-child(3) { + left: 0; + transform: rotate(-45deg) translate(5px, -5px);; + width: 100%; } } } } + /* * * * * * * * * * * * * * * * * * * * * * * * * * */ /* M U L T I P U R P O S E S E A R C H B A R */ /* * * * * * * * * * * * * * * * * * * * * * * * * * */