From 2330d5f39426b2078c8be612034e2ae020b38ba8 Mon Sep 17 00:00:00 2001 From: Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de> Date: Tue, 19 Sep 2023 10:42:59 +0000 Subject: [PATCH] add separator element to ActionMenu, fixes #3013 Closes #3013 Merge request studip/studip!2017 --- lib/classes/ActionMenu.php | 33 +++++++++++++++++-- .../assets/stylesheets/scss/actionmenu.scss | 6 ++++ resources/vue/components/StudipActionMenu.vue | 9 ++--- templates/shared/action-menu-single.php | 2 ++ templates/shared/action-menu.php | 2 ++ 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/classes/ActionMenu.php b/lib/classes/ActionMenu.php index 6fc016a2e7c..aa6c5240e47 100644 --- a/lib/classes/ActionMenu.php +++ b/lib/classes/ActionMenu.php @@ -96,6 +96,18 @@ class ActionMenu return $result; } + /** + * Returns the number of action menu items (not counting separators). + * + * @return int count + */ + protected function countActions(): int + { + return count(array_filter($this->actions, function($action) { + return $action['type'] !== 'separator'; + })); + } + /** * Adds a link to the list of actions. * @@ -213,6 +225,23 @@ class ActionMenu return $this; } + /** + * Adds a separator line to the list of actions. + * + * @return ActionMenu instance to allow chaining + */ + public function addSeparator(): ActionMenu + { + if ($this->checkCondition()) { + $this->actions[] = [ + 'type' => 'separator', + 'index' => '' + ]; + } + + return $this; + } + /** * Adds a css classs to the root element in html. * @@ -251,7 +280,7 @@ class ActionMenu */ public function render() { - if (count($this->actions) === 0) { + if ($this->countActions() === 0) { return ''; } @@ -342,7 +371,7 @@ class ActionMenu $rendering_mode = $this->rendering_mode; if ($rendering_mode === null) { - $rendering_mode = count($this->actions) <= Config::get()->ACTION_MENU_THRESHOLD + $rendering_mode = $this->countActions() <= Config::get()->ACTION_MENU_THRESHOLD ? self::RENDERING_MODE_ICONS : self::RENDERING_MODE_MENU; } diff --git a/resources/assets/stylesheets/scss/actionmenu.scss b/resources/assets/stylesheets/scss/actionmenu.scss index 588f50c0391..56b1317c412 100644 --- a/resources/assets/stylesheets/scss/actionmenu.scss +++ b/resources/assets/stylesheets/scss/actionmenu.scss @@ -141,6 +141,12 @@ $action-menu-shadow: 1px 1px 1px $dark-gray-color-60; color: $active-color; } } + + > hr { + border-style: none; + border-top: thin solid var(--dark-gray-color-45); + margin: 4px 0; + } } &.is-open { diff --git a/resources/vue/components/StudipActionMenu.vue b/resources/vue/components/StudipActionMenu.vue index d67f6a230f4..014a1cacefc 100644 --- a/resources/vue/components/StudipActionMenu.vue +++ b/resources/vue/components/StudipActionMenu.vue @@ -11,10 +11,10 @@ </div> <ul class="action-menu-list"> <li v-for="item in navigationItems" :key="item.id" class="action-menu-item"> - <a v-if="item.type === 'link'" v-bind="linkAttributes(item)" v-on="linkEvents(item)"> + <hr v-if="item.type === 'separator'"> + <a v-else-if="item.type === 'link'" v-bind="linkAttributes(item)" v-on="linkEvents(item)"> <studip-icon v-if="item.icon !== false" :shape="item.icon.shape" :role="item.icon.role"></studip-icon> <span v-else class="action-menu-no-icon"></span> - {{ item.label }} </a> <label v-else-if="item.icon" class="undecorated" v-bind="linkAttributes(item)" v-on="linkEvents(item)"> @@ -33,7 +33,8 @@ </div> <div 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> + <span v-if="item.type === 'separator'" class="quiet">|</span> + <studip-icon v-else :title="item.label" :shape="item.icon.shape" :role="item.icon.role" :size="20"></studip-icon> </a> </div> </template> @@ -119,7 +120,7 @@ export default { if (collapseAt === true) { return true; } - return Number.parseInt(collapseAt) <= this.items.length; + return Number.parseInt(collapseAt) <= this.items.filter((item) => item.type !== 'separator').length; }, title () { return this.context ? this.$gettextInterpolate(this.$gettext('Aktionsmenü für %{context}'), {context: this.context}) : this.$gettext('Aktionsmenü'); diff --git a/templates/shared/action-menu-single.php b/templates/shared/action-menu-single.php index a34a01e69dc..455bc44a6ba 100644 --- a/templates/shared/action-menu-single.php +++ b/templates/shared/action-menu-single.php @@ -30,5 +30,7 @@ <? endif ?> <? elseif ($action['type'] === 'multi-person-search'): ?> <?= $action['object']->render(false) ?> + <? elseif ($action['type'] === 'separator'): ?> + <span class="quiet">|</span> <? endif ?> <? endforeach ?> diff --git a/templates/shared/action-menu.php b/templates/shared/action-menu.php index c781f333859..4f3b5f10ff9 100644 --- a/templates/shared/action-menu.php +++ b/templates/shared/action-menu.php @@ -48,6 +48,8 @@ <? endif ?> <? elseif ($action['type'] === 'multi-person-search'): ?> <?= $action['object']->render() ?> + <? elseif ($action['type'] === 'separator'): ?> + <hr> <? endif ?> </li> <? endforeach ?> -- GitLab