How to connect EditorJS in admiral
10 minutes
Tools
Admiral
Feb 27, 2024
10 minutes
php
class MenuService
{
function menu(): Menu
{
return Menu::make()
->addItem(MenuItem::make(MenuKey::PRODUCTS, 'Products', 'FiProduct', "/products"));
function permissions(): array
{
$result = [];
foreach ($this->menu()->items() as $menuItem) {
if ($menuItem->isParent()) {
$result[] = [
'value' => $menuItem->key()->value,
'label' => $menuItem->name(),
];
continue;
}
foreach ($menuItem->children()->items() as $child) {
$result[] = [
'value' => $child->key()->value,
'label' => $menuItem->name() . '->' . $child->name(),
];
}
}
return $result;
}
public function userMenu(User $user): array
{
$menu = $this->menu();
$permissions = $user->role?->permissions ?? [];
if ($user->role?->title == Role::ADMIN) {
$permissions = collect(MenuKey::cases())->pluck('value')->toArray();
}
$badge = new Badge($user, $permissions);
return $menu->toArray($permissions, $badge);
}
public function toFromKey(string $permission): ?string
{
return match (MenuKey::tryFrom($permission)) {
MenuKey::PRODUCTS => "/products",
default => null,
};
}
}
php
class Menu
{
protected array $items = [];
protected ?string $prefix = null;
public static function make(): static
{
return new static();
}
/**
* @return array|MenuItem[]
*/
public function items(): array
{
return $this->items;
}
public function addItem(MenuItem $item): static
{
$this->items[] = $item;
return $this;
}
public function toArray(array $permissions, Badge $badge): array
{
return collect($this->items)
->map(fn (MenuItem|Menu $item) => $item->toArray($permissions, $badge))
->filter()
->values()
->toArray();
}
}
php
class MenuItem
{
protected ?Menu $children = null;
protected ?string $to = null;
public function __construct(
private MenuKey $key,
private string $title,
private string $icon,
string|Menu $value,
) {
if (is_string($value)) {
$this->to = $value;
return;
}
$this->children = $value;
}
public static function make(...$args): static
{
return new static(...$args);
}
public function isParent(): bool
{
return !!$this->to;
}
public function name(): string
{
return $this->title;
}
public function to(): string
{
return $this->to;
}
public function key(): MenuKey
{
return $this->key;
}
public function children(): ?Menu
{
return $this->children;
}
public function toArray(array $permissions, Badge $badge): ?array
{
$data = [
'name' => $this->title,
'icon' => $this->icon,
'badge' => $badge->get($this->key),
];
if ($this->children) {
$data['children'] = $this->children->toArray($permissions, $badge);
if (!$data['children']) {
return null;
}
return $data;
}
if (!in_array($this->key->value, $permissions)) {
return null;
}
$data['to'] = $this->to;
return $data;
}
}
php
'badge' => $badge->get($this->key),
php
class Badge
{
protected Collection $badges;
public function __construct(User $user, array $permissions)
{
$this->badges = $this->getBadges($user, $permissions)->keyBy('type');
}
public function get(MenuKey $key): ?int
{
return match ($key) {
MenuKey::PRODUCTS => $this->findByType(MenuKey::PRODUCTS),
default => null,
};
}
protected function findByTypes(array $types): ?int
{
$sum = 0;
foreach ($types as $type) {
$sum = $sum + $this->findByType($type);
}
return $sum > 0 ? $sum : null;
}
protected function findByType(MenuKey $key): ?int
{
return $this->badges->get($key->value)?->count;
}
private function getBadges(User $user, array $permissions): Collection
{
$queries = [];
foreach ($permissions as $permission) {
$q = MenuKey::tryFrom($permission) ? $this->query($user, MenuKey::tryFrom($permission)) : null;
if ($q) {
$queries[] = $q;
}
}
if (!count($queries)) {
return collect();
}
$badgeQuery = DB::query();
foreach ($queries as $key => $query) {
if ($key == 0) {
$badgeQuery->fromSub($query, 'badge_count');
continue;
}
$badgeQuery->unionAll($query);
}
return $badgeQuery->get();
}
protected function query(
User $user,
MenuKey $key
): \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Query\Builder|null {
return match ($key) {
MenuKey::PRODUCTS => $this->productsQuery($user),
default => null,
};
}
private function productsQuery(User $user): \Illuminate\Database\Eloquent\Builder
{
return Products::query()
->selectRaw("count(*) as count, '" . MenuKey::PRODUCTS->value . "' as type")
->where('status', ProductStatus::NEW);
}
}
php
MenuKey::ORDERS => $this->findByType(MenuKey::ORDERS),
php
MenuKey::ORDERS => $this->ordersQuery($user),
typescript
<MenuItemLink
key={`${i}`}
icon={menu.icon}
name={menu.name}
to={menu.to}
badge={{ count: menu.badge, status: 'error' }}
/>