Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Menu/MenuItem as Ui Components #6970

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion panel/src/components/View/Inside.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
<template>
<k-panel class="k-panel-inside">
<k-panel-menu />
<k-panel-menu
v-bind="$panel.menu.props"
:hover="$panel.menu.hover"
:is-open="$panel.menu.isOpen"
:license="$panel.license"
:searches="$panel.searches"
@hover="$panel.menu.hover = $event"
@search="$panel.search()"
@toggle="$panel.menu.toggle()"
/>
<main class="k-panel-main">
<k-topbar :breadcrumb="$panel.view.breadcrumb" :view="$panel.view">
<!-- @slot Additional content for the Topbar -->
Expand Down
53 changes: 34 additions & 19 deletions panel/src/components/View/Menu.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<nav
class="k-panel-menu"
:aria-label="$t('menu')"
:data-hover="$panel.menu.hover"
@mouseenter="$panel.menu.hover = true"
@mouseleave="$panel.menu.hover = false"
:data-hover="hover"
@mouseenter="$emit('hover', true)"
@mouseleave="$emit('hover', false)"
>
<div class="k-panel-menu-body">
<!-- Search button -->
Expand All @@ -13,7 +13,7 @@
:text="$t('search')"
icon="search"
class="k-panel-menu-search k-panel-menu-button"
@click="$panel.search()"
@click="$emit('search')"
/>

<!-- Menus -->
Expand All @@ -23,13 +23,14 @@
:data-second-last="menuIndex === menus.length - 2"
class="k-panel-menu-buttons"
>
<k-button
v-for="entry in menu"
:key="entry.id"
v-bind="entry"
:title="entry.title ?? entry.text"
class="k-panel-menu-button"
/>
<template v-for="entry in menu">
<component
:is="entry.component"
:key="entry.key"
v-bind="entry.props"
class="k-panel-menu-button"
/>
</template>
</menu>

<menu v-if="activationButton">
Expand All @@ -40,17 +41,17 @@
theme="love"
variant="filled"
/>
<k-activation :status="$panel.license" />
<k-activation :status="license" />
</menu>
</div>

<!-- Collapse/expand toggle -->
<k-button
:icon="$panel.menu.isOpen ? 'angle-left' : 'angle-right'"
:title="$panel.menu.isOpen ? $t('collapse') : $t('expand')"
:icon="isOpen ? 'angle-left' : 'angle-right'"
:title="isOpen ? $t('collapse') : $t('expand')"
size="xs"
class="k-panel-menu-toggle"
@click="$panel.menu.toggle()"
@click="$emit('toggle')"
/>
</nav>
</template>
Expand All @@ -61,21 +62,35 @@
* @internal
*/
export default {
props: {
hover: Boolean,
isOpen: Boolean,
items: {
type: Array,
default: () => []
},
license: String,
searches: {
type: Object,
default: () => ({})
}
},
emits: ["search", "toggle"],
data() {
return {
over: false
};
},
computed: {
activationButton() {
if (this.$panel.license === "missing") {
if (this.license === "missing") {
return {
click: () => this.$dialog("registration"),
text: this.$t("activate")
};
}

if (this.$panel.license === "legacy") {
if (this.license === "legacy") {
return {
click: () => this.$dialog("license"),
text: this.$t("renew")
Expand All @@ -85,10 +100,10 @@ export default {
return false;
},
hasSearch() {
return this.$helper.object.length(this.$panel.searches) > 0;
return this.$helper.object.length(this.searches) > 0;
},
menus() {
return this.$helper.array.split(this.$panel.menu.entries, "-");
return this.$helper.array.split(this.items, "-");
}
}
};
Expand Down
6 changes: 3 additions & 3 deletions panel/src/panel/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import State from "./state.js";

export const defaults = () => {
return {
entries: [],
props: {},
hover: false,
isOpen: false
};
Expand Down Expand Up @@ -100,8 +100,8 @@ export default (panel) => {
*
* @param {Array} entries
*/
set(entries) {
this.entries = entries;
set(menu) {
this.props = menu.props;
this.resize();
return this.state();
},
Expand Down
10 changes: 5 additions & 5 deletions src/Panel/Area.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,11 @@ public function menuItem(
// create a new menu item instance for the area
$item = new MenuItem(
current: $this->isCurrent($current),
icon: $this->icon() ?? $this->id(),
text: $this->label(),
dialog: $this->dialog(),
drawer: $this->drawer(),
link: $this->link(),
icon: $this->icon() ?? $this->id(),
text: $this->label(),
dialog: $this->dialog(),
drawer: $this->drawer(),
link: $this->link(),
);

// add the custom menu settings
Expand Down
9 changes: 5 additions & 4 deletions src/Panel/Fiber.php
Original file line number Diff line number Diff line change
Expand Up @@ -213,12 +213,13 @@ public function license(): string
public function menu(): array
{
$menu = new Menu(
$this->areas,
$this->permissions,
$this->area?->id()
areas: $this->areas,
permissions: $this->permissions,
current: $this->area?->id(),
config: $this->kirby->option('panel.menu', null)
);

return $menu->items();
return $menu->render();
}

public function multilang(): bool
Expand Down
8 changes: 4 additions & 4 deletions src/Panel/Home.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,22 +73,22 @@ public function alternative(): string
}

// skip disabled items
if (($menuItem['disabled'] ?? false) === true) {
if (($menuItem['props']['disabled'] ?? false) === true) {
continue;
}

// skip buttons that don't open a link
// (but e.g. a dialog)
if (isset($menuItem['link']) === false) {
if (isset($menuItem['props']['link']) === false) {
continue;
}

// skip the logout button
if ($menuItem['link'] === 'logout') {
if ($menuItem['props']['link'] === 'logout') {
continue;
}

return Panel::url($menuItem['link']);
return Panel::url($menuItem['props']['link']);
}

throw new NotFoundException(
Expand Down
79 changes: 54 additions & 25 deletions src/Panel/Ui/Menu.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
use Closure;
use Kirby\Cms\App;
use Kirby\Panel\Area;
use Kirby\Toolkit\A;

/**
* The Menu class takes care of gathering
Expand All @@ -17,18 +18,23 @@
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
*/
class Menu
class Menu extends Component
{
protected array $areas = [];

public function __construct(
array $areas = [],
protected array $permissions = [],
protected string|null $current = null
protected string|null $current = null,
protected Closure|array|null $config = null
) {
foreach ($areas as $area) {
$this->areas[$area->id()] = $area;
}

parent::__construct(
component: 'k-panel-menu'
);
}

/**
Expand All @@ -54,6 +60,12 @@ public function areas(): array
continue;
}

// [$areaId => Ui() ]
if ($area instanceof Component) {
$areas[] = $area;
continue;
}

// [0 => $areaId]
if (is_numeric($id) === true) {
$areas[] = $this->area($area);
Expand Down Expand Up @@ -91,21 +103,21 @@ public function areas(): array
public function config(): array
{
// get from config option which areas should be listed in the menu
$kirby = App::instance();
$items = $kirby->option('panel.menu');
$items = $this->config;

// lazy-load items
if ($items instanceof Closure) {
$kirby = App::instance();
$items = $items($kirby);
}

// if no config is defined…
if ($items === null) {
// ensure that some defaults are on top in the right order
$defaults = ['site', 'languages', 'users', 'system'];
$default = ['site', 'languages', 'users', 'system'];
// add all other areas after that
$additionals = array_diff(array_keys($this->areas), $defaults);
$items = [...$defaults, ...$additionals];
$additional = array_diff(array_keys($this->areas), $default);
$items = [...$default, ...$additional];
}

return $items;
Expand All @@ -122,9 +134,9 @@ public function item(Area|null $area): MenuItem|null
}

return $area->menuItem(
areas: $this->areas,
areas: $this->areas,
permissions: $this->permissions,
current: $this->current
current: $this->current
);
}

Expand All @@ -133,19 +145,28 @@ public function item(Area|null $area): MenuItem|null
*/
public function items(): array
{
$items = [];

foreach ($this->areas() as $area) {
if ($area === '-') {
$items[] = '-';
} elseif ($item = $this->item($area)) {
$items[] = $item->toArray();
$items = A::map(
$this->areas(),
function (Area|Component|string $area) {
if ($area === '-') {
return '-';
}

if ($area instanceof Component) {
return $area->render();
}

if ($item = $this->item($area)) {
return $item->render();
}
}
}

$items[] = '-';
);

return array_filter([...$items, ...$this->options()]);
return array_filter([
...$items,
'-',
...$this->options()
]);
}

/**
Expand All @@ -155,9 +176,9 @@ public function items(): array
public function options(): array
{
$changes = new MenuItem(
icon: 'edit-line',
icon: 'edit-line',
dialog: 'changes',
text: 'changes'
text: 'changes'
);

$account = new MenuItem(
Expand All @@ -175,9 +196,17 @@ public function options(): array
);

return [
$changes->toArray(),
$account->toArray(),
$logout->toArray(),
$changes->render(),
$account->render(),
$logout->render(),
];
}

public function props(): array
{
return [
...parent::props(),
'items' => $this->items()
];
}
}
Loading
Loading